1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-10 18:43:28 -05:00

WDSP: Sonar lint fixes (2)

This commit is contained in:
f4exb 2024-08-03 11:05:12 +02:00
parent 8941835466
commit d6159067a8
37 changed files with 1091 additions and 1183 deletions

1
.gitignore vendored
View File

@ -28,6 +28,7 @@ obj-x86_64-linux-gnu/*
**/venv*/
*.pyc
.DS_Store
.sonarlint
### Go ###
# Binaries for programs and plugins

View File

@ -25,6 +25,8 @@ warren@wpratt.com
*/
#include <cstdio>
#include "comm.hpp"
#include "amsq.hpp"
@ -174,7 +176,7 @@ void AMSQ::execute()
}
else if (count-- == 0)
{
state = AMSQState::TAIL;
state = AMSQState::DECREASE;
count = ntdown;
}

View File

@ -42,332 +42,124 @@ namespace WDSP {
********************************************************************************************************/
float* EQ::eq_mults (int size, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype)
void EQ::eq_mults (std::vector<float>& mults, int size, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype)
{
float* impulse = EQP::eq_impulse (size + 1, nfreqs, F, G, samplerate, scale, ctfmode, wintype);
float* mults = FIR::fftcv_mults(2 * size, impulse);
delete[] (impulse);
return mults;
float* _mults = FIR::fftcv_mults(2 * size, impulse);
mults.resize(2 * size * 2);
std::copy(_mults, _mults + 2*size*2, mults.begin());
delete[] _mults;
delete[] impulse;
}
void EQ::calc_eq (EQ *a)
void EQ::calc()
{
a->scale = 1.0 / (float)(2 * a->size);
a->infilt = new float[2 * a->size * 2]; // (float *)malloc0(2 * a->size * sizeof(complex));
a->product = new float[2 * a->size * 2]; // (float *)malloc0(2 * a->size * sizeof(complex));
a->CFor = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->infilt, (fftwf_complex *)a->product, FFTW_FORWARD, FFTW_PATIENT);
a->CRev = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->product, (fftwf_complex *)a->out, FFTW_BACKWARD, FFTW_PATIENT);
a->mults = EQ::eq_mults(a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
scale = (float) (1.0 / (float)(2 * size));
infilt.resize(2 * size * 2);
product.resize(2 * size * 2);
CFor = fftwf_plan_dft_1d(
2 * size,
(fftwf_complex *) infilt.data(),
(fftwf_complex *) product.data(),
FFTW_FORWARD,
FFTW_PATIENT
);
CRev = fftwf_plan_dft_1d(
2 * size,
(fftwf_complex *) product.data(),
(fftwf_complex *) out,
FFTW_BACKWARD,
FFTW_PATIENT
);
EQ::eq_mults(mults, size, nfreqs, F.data(), G.data(), samplerate, scale, ctfmode, wintype);
}
void EQ::decalc_eq (EQ *a)
void EQ::decalc()
{
fftwf_destroy_plan(a->CRev);
fftwf_destroy_plan(a->CFor);
delete[] (a->mults);
delete[] (a->product);
delete[] (a->infilt);
fftwf_destroy_plan(CRev);
fftwf_destroy_plan(CFor);
}
EQ* EQ::create_eq (int run, int size, float *in, float *out, int nfreqs, float* F, float* G, int ctfmode, int wintype, int samplerate)
EQ::EQ(
int _run,
int _size,
float *_in,
float *_out,
int _nfreqs,
const float* _F,
const float* _G,
int _ctfmode,
int _wintype,
int _samplerate
) :
run(_run),
size(_size),
in(_in),
out(_out),
nfreqs(_nfreqs),
ctfmode(_ctfmode),
wintype(_wintype),
samplerate((float) _samplerate)
{
EQ *a = new EQ;
a->run = run;
a->size = size;
a->in = in;
a->out = out;
a->nfreqs = nfreqs;
a->F = new float[a->nfreqs + 1]; // (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->G = new float[a->nfreqs + 1]; // (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
memcpy (a->F, F, (nfreqs + 1) * sizeof (float));
memcpy (a->G, G, (nfreqs + 1) * sizeof (float));
a->ctfmode = ctfmode;
a->wintype = wintype;
a->samplerate = (float)samplerate;
calc_eq (a);
return a;
F.resize(nfreqs + 1);
G.resize(nfreqs + 1);
std::copy(_F, _F + nfreqs + 1, F.begin());
std::copy(_G, _G + nfreqs + 1, G.begin());
calc();
}
void EQ::destroy_eq (EQ *a)
EQ::~EQ()
{
decalc_eq (a);
delete[] (a->G);
delete[] (a->F);
delete[] (a);
decalc();
}
void EQ::flush_eq (EQ *a)
void EQ::flush()
{
std::fill(a->infilt, a->infilt + 2 * a->size * 2, 0);
std::fill(infilt.begin(), infilt.end(), 0);
}
void EQ::xeq (EQ *a)
void EQ::execute()
{
int i;
float I, Q;
if (a->run)
float I;
float Q;
if (run)
{
std::copy(a->in, a->in + a->size * 2, &(a->infilt[2 * a->size]));
fftwf_execute (a->CFor);
for (i = 0; i < 2 * a->size; i++)
std::copy(in, in + size * 2, &(infilt[2 * size]));
fftwf_execute (CFor);
for (int i = 0; i < 2 * size; i++)
{
I = a->product[2 * i + 0];
Q = a->product[2 * i + 1];
a->product[2 * i + 0] = I * a->mults[2 * i + 0] - Q * a->mults[2 * i + 1];
a->product[2 * i + 1] = I * a->mults[2 * i + 1] + Q * a->mults[2 * i + 0];
I = product[2 * i + 0];
Q = product[2 * i + 1];
product[2 * i + 0] = I * mults[2 * i + 0] - Q * mults[2 * i + 1];
product[2 * i + 1] = I * mults[2 * i + 1] + Q * mults[2 * i + 0];
}
fftwf_execute (a->CRev);
std::copy(&(a->infilt[2 * a->size]), &(a->infilt[2 * a->size]) + a->size * 2, a->infilt);
fftwf_execute (CRev);
std::copy(&(infilt[2 * size]), &(infilt[2 * size]) + size * 2, infilt);
}
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 EQ::setBuffers_eq (EQ *a, float* in, float* out)
void EQ::setBuffers(float* _in, float* _out)
{
decalc_eq (a);
a->in = in;
a->out = out;
calc_eq (a);
decalc();
in = _in;
out = _out;
calc();
}
void EQ::setSamplerate_eq (EQ *a, int rate)
void EQ::setSamplerate(int _rate)
{
decalc_eq (a);
a->samplerate = rate;
calc_eq (a);
decalc();
samplerate = (float) _rate;
calc();
}
void EQ::setSize_eq (EQ *a, int size)
void EQ::setSize(int _size)
{
decalc_eq (a);
a->size = size;
calc_eq (a);
decalc();
size = _size;
calc();
}
/********************************************************************************************************
* *
* Overlap-Save Equalizer: RXA Properties *
* *
********************************************************************************************************/
/* // UNCOMMENT properties when a pointer is in place in rxa
PORT
void SetRXAEQRun (int channel, int run)
{
ch.csDSP.lock();
rxa.eq->run = run;
ch.csDSP.unlock();
}
PORT
void SetRXAEQProfile (int channel, int nfreqs, float* F, float* G)
{
EQ a;
ch.csDSP.lock();
a = rxa.eq;
delete[] (a->G);
delete[] (a->F);
a->nfreqs = nfreqs;
a->F = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->G = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
memcpy (a->F, F, (nfreqs + 1) * sizeof (float));
memcpy (a->G, G, (nfreqs + 1) * sizeof (float));
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
PORT
void SetRXAEQCtfmode (int channel, int mode)
{
EQ a;
ch.csDSP.lock();
a = rxa.eq;
a->ctfmode = mode;
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
PORT
void SetRXAEQWintype (int channel, int wintype)
{
EQ a;
ch.csDSP.lock();
a = rxa.eq;
a->wintype = wintype;
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
PORT
void SetRXAGrphEQ (int channel, int *rxeq)
{ // three band equalizer (legacy compatibility)
EQ a;
ch.csDSP.lock();
a = rxa.eq;
delete[] (a->G);
delete[] (a->F);
a->nfreqs = 4;
a->F = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->G = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->F[1] = 150.0;
a->F[2] = 400.0;
a->F[3] = 1500.0;
a->F[4] = 6000.0;
a->G[0] = (float)rxeq[0];
a->G[1] = (float)rxeq[1];
a->G[2] = (float)rxeq[1];
a->G[3] = (float)rxeq[2];
a->G[4] = (float)rxeq[3];
a->ctfmode = 0;
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
PORT
void SetRXAGrphEQ10 (int channel, int *rxeq)
{ // ten band equalizer (legacy compatibility)
EQ a;
int i;
ch.csDSP.lock();
a = rxa.eq;
delete[] (a->G);
delete[] (a->F);
a->nfreqs = 10;
a->F = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->G = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->F[1] = 32.0;
a->F[2] = 63.0;
a->F[3] = 125.0;
a->F[4] = 250.0;
a->F[5] = 500.0;
a->F[6] = 1000.0;
a->F[7] = 2000.0;
a->F[8] = 4000.0;
a->F[9] = 8000.0;
a->F[10] = 16000.0;
for (i = 0; i <= a->nfreqs; i++)
a->G[i] = (float)rxeq[i];
a->ctfmode = 0;
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
*/
/********************************************************************************************************
* *
* Overlap-Save Equalizer: TXA Properties *
* *
********************************************************************************************************/
/* // UNCOMMENT properties when a pointer is in place in rxa
PORT
void SetTXAEQRun (int channel, int run)
{
ch.csDSP.lock();
txa.eq->run = run;
ch.csDSP.unlock();
}
PORT
void SetTXAEQProfile (int channel, int nfreqs, float* F, float* G)
{
EQ a;
ch.csDSP.lock();
a = txa.eq;
delete[] (a->G);
delete[] (a->F);
a->nfreqs = nfreqs;
a->F = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->G = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
memcpy (a->F, F, (nfreqs + 1) * sizeof (float));
memcpy (a->G, G, (nfreqs + 1) * sizeof (float));
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
PORT
void SetTXAEQCtfmode (int channel, int mode)
{
EQ a;
ch.csDSP.lock();
a = txa.eq;
a->ctfmode = mode;
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
PORT
void SetTXAEQMethod (int channel, int wintype)
{
EQ a;
ch.csDSP.lock();
a = txa.eq;
a->wintype = wintype;
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
PORT
void SetTXAGrphEQ (int channel, int *txeq)
{ // three band equalizer (legacy compatibility)
EQ a;
ch.csDSP.lock();
a = txa.eq;
delete[] (a->G);
delete[] (a->F);
a->nfreqs = 4;
a->F = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->G = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->F[1] = 150.0;
a->F[2] = 400.0;
a->F[3] = 1500.0;
a->F[4] = 6000.0;
a->G[0] = (float)txeq[0];
a->G[1] = (float)txeq[1];
a->G[2] = (float)txeq[1];
a->G[3] = (float)txeq[2];
a->G[4] = (float)txeq[3];
a->ctfmode = 0;
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
PORT
void SetTXAGrphEQ10 (int channel, int *txeq)
{ // ten band equalizer (legacy compatibility)
EQ a;
int i;
ch.csDSP.lock();
a = txa.eq;
delete[] (a->G);
delete[] (a->F);
a->nfreqs = 10;
a->F = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->G = (float *) malloc0 ((a->nfreqs + 1) * sizeof (float));
a->F[1] = 32.0;
a->F[2] = 63.0;
a->F[3] = 125.0;
a->F[4] = 250.0;
a->F[5] = 500.0;
a->F[6] = 1000.0;
a->F[7] = 2000.0;
a->F[8] = 4000.0;
a->F[9] = 8000.0;
a->F[10] = 16000.0;
for (i = 0; i <= a->nfreqs; i++)
a->G[i] = (float)txeq[i];
a->ctfmode = 0;
delete[] (a->mults);
a->mults = eq_mults (a->size, a->nfreqs, a->F, a->G, a->samplerate, a->scale, a->ctfmode, a->wintype);
ch.csDSP.unlock();
}
*/
} // namespace WDSP

View File

@ -34,6 +34,8 @@ warren@wpratt.com
#ifndef wdsp_eq_h
#define wdsp_eq_h
#include <vector>
#include "fftw3.h"
#include "export.h"
@ -47,11 +49,11 @@ public:
float* in;
float* out;
int nfreqs;
float* F;
float* G;
float* infilt;
float* product;
float* mults;
std::vector<float> F;
std::vector<float> G;
std::vector<float> infilt;
std::vector<float> product;
std::vector<float> mults;
float scale;
int ctfmode;
int wintype;
@ -59,19 +61,32 @@ public:
fftwf_plan CFor;
fftwf_plan CRev;
static EQ* create_eq (int run, int size, float *in, float *out, int nfreqs, float* F, float* G, int ctfmode, int wintype, int samplerate);
// static float* eq_mults (int size, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype);
static void destroy_eq (EQ *a);
static void flush_eq (EQ *a);
static void xeq (EQ *a);
static void setBuffers_eq (EQ *a, float* in, float* out);
static void setSamplerate_eq (EQ *a, int rate);
static void setSize_eq (EQ *a, int size);
EQ(
int run,
int size,
float *in,
float *out,
int nfreqs,
const float* F,
const float* G,
int ctfmode,
int wintype,
int samplerate
);
EQ(const EQ&) = delete;
EQ& operator=(EQ& other) = delete;
~EQ() = default;
void flush();
void execute();
void setBuffers(float* in, float* out);
void setSamplerate(int rate);
void setSize(int size);
private:
static float* eq_mults (int size, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype);
static void calc_eq (EQ *a);
static void decalc_eq (EQ *a);
static void eq_mults (std::vector<float>& mults, int size, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype);
void calc();
void decalc();
};
} // namespace WDSP

View File

@ -42,22 +42,27 @@ int EQP::fEQcompare (const void * a, const void * b)
return 1;
}
float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate, double scale, int ctfmode, int wintype)
float* EQP::eq_impulse (int N, int nfreqs, const float* F, const float* G, double samplerate, double scale, int ctfmode, int wintype)
{
float* fp = new float[nfreqs + 2]; // (float *) malloc0 ((nfreqs + 2) * sizeof (float));
float* gp = new float[nfreqs + 2]; // (float *) malloc0 ((nfreqs + 2) * sizeof (float));
float* A = new float[N / 2 + 1]; // (float *) malloc0 ((N / 2 + 1) * sizeof (float));
float* sary = new float[2 * nfreqs]; // (float *) malloc0 (2 * nfreqs * sizeof (float));
double gpreamp, f, frac;
std::vector<float> fp(nfreqs + 2);
std::vector<float> gp(nfreqs + 2);
std::vector<float> A(N / 2 + 1);
float* sary = new float[2 * nfreqs];
double gpreamp;
double f;
double frac;
float* impulse;
int i, j, mid;
int i;
int j;
int mid;
fp[0] = 0.0;
fp[nfreqs + 1] = 1.0;
gpreamp = G[0];
for (i = 1; i <= nfreqs; i++)
{
fp[i] = 2.0 * F[i] / samplerate;
fp[i] = (float) (2.0 * F[i] / samplerate);
if (fp[i] < 0.0)
fp[i] = 0.0;
@ -97,7 +102,7 @@ float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate
j++;
frac = (f - fp[j]) / (fp[j + 1] - fp[j]);
A[i] = pow (10.0, 0.05 * (frac * gp[j + 1] + (1.0 - frac) * gp[j] + gpreamp)) * scale;
A[i] = (float) (pow (10.0, 0.05 * (frac * gp[j + 1] + (1.0 - frac) * gp[j] + gpreamp)) * scale);
}
}
else
@ -110,14 +115,19 @@ float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate
j++;
frac = (f - fp[j]) / (fp[j + 1] - fp[j]);
A[i] = pow (10.0, 0.05 * (frac * gp[j + 1] + (1.0 - frac) * gp[j] + gpreamp)) * scale;
A[i] = (float) (pow (10.0, 0.05 * (frac * gp[j + 1] + (1.0 - frac) * gp[j] + gpreamp)) * scale);
}
}
if (ctfmode == 0)
{
int k, low, high;
double lowmag, highmag, flow4, fhigh4;
int k;
int low;
int high;
double lowmag;
double highmag;
double flow4;
double fhigh4;
if (N & 1)
{
@ -134,7 +144,7 @@ float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate
f = (double)k / (double)mid;
lowmag *= (f * f * f * f) / flow4;
if (lowmag < 1.0e-20) lowmag = 1.0e-20;
A[k] = lowmag;
A[k] = (float) lowmag;
}
k = high;
@ -144,7 +154,7 @@ float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate
f = (double)k / (double)mid;
highmag *= fhigh4 / (f * f * f * f);
if (highmag < 1.0e-20) highmag = 1.0e-20;
A[k] = highmag;
A[k] = (float) highmag;
}
}
else
@ -162,7 +172,7 @@ float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate
f = (double)k / (double)mid;
lowmag *= (f * f * f * f) / flow4;
if (lowmag < 1.0e-20) lowmag = 1.0e-20;
A[k] = lowmag;
A[k] = (float) lowmag;
}
k = high;
@ -172,21 +182,17 @@ float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate
f = (double)k / (double)mid;
highmag *= fhigh4 / (f * f * f * f);
if (highmag < 1.0e-20) highmag = 1.0e-20;
A[k] = highmag;
A[k] = (float) highmag;
}
}
}
if (N & 1)
impulse = FIR::fir_fsamp_odd(N, A, 1, 1.0, wintype);
impulse = FIR::fir_fsamp_odd(N, A.data(), 1, 1.0, wintype);
else
impulse = FIR::fir_fsamp(N, A, 1, 1.0, wintype);
impulse = FIR::fir_fsamp(N, A.data(), 1, 1.0, wintype);
// print_impulse("eq.txt", N, impulse, 1, 0);
delete[] (sary);
delete[] (A);
delete[] (gp);
delete[] (fp);
delete[] sary;
return impulse;
}
@ -220,8 +226,8 @@ EQP::EQP(
in = _in;
out = _out;
nfreqs = _nfreqs;
F.resize(nfreqs + 1); // (float *) malloc0 ((nfreqs + 1) * sizeof (float));
G.resize(nfreqs + 1); // (float *) malloc0 ((nfreqs + 1) * sizeof (float));
F.resize(nfreqs + 1);
G.resize(nfreqs + 1);
std::copy(_F, _F + (_nfreqs + 1), F.begin());
std::copy(_G, _G + (_nfreqs + 1), G.begin());
ctfmode = _ctfmode;
@ -229,7 +235,7 @@ EQP::EQP(
samplerate = (double) _samplerate;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
fircore = FIRCORE::create_fircore (size, in, out, nc, mp, impulse);
delete[] (impulse);
delete[] impulse;
}
EQP::~EQP()
@ -263,7 +269,7 @@ void EQP::setSamplerate(int rate)
samplerate = rate;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
void EQP::setSize(int _size)
@ -273,7 +279,7 @@ void EQP::setSize(int _size)
FIRCORE::setSize_fircore (fircore, size);
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
/********************************************************************************************************
@ -296,7 +302,7 @@ void EQP::setNC(int _nc)
nc = _nc;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
FIRCORE::setNc_fircore (fircore, nc, impulse);
delete[] (impulse);
delete[] impulse;
}
}
@ -313,13 +319,13 @@ void EQP::setProfile(int _nfreqs, const float* _F, const float* _G)
{
float* impulse;
nfreqs = _nfreqs;
F.resize(nfreqs + 1); // (float *) malloc0 ((nfreqs + 1) * sizeof (float));
G.resize(nfreqs + 1); // (float *) malloc0 ((nfreqs + 1) * sizeof (float));
F.resize(nfreqs + 1);
G.resize(nfreqs + 1);
std::copy(_F, _F + (_nfreqs + 1), F.begin());
std::copy(_G, _G + (_nfreqs + 1), G.begin());
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
void EQP::setCtfmode(int _mode)
@ -328,7 +334,7 @@ void EQP::setCtfmode(int _mode)
ctfmode = _mode;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
void EQP::setWintype(int _wintype)
@ -337,15 +343,15 @@ void EQP::setWintype(int _wintype)
wintype = _wintype;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
void EQP::setGrphEQ(int *rxeq)
void EQP::setGrphEQ(const int *rxeq)
{ // three band equalizer (legacy compatibility)
float* impulse;
nfreqs = 4;
F.resize(nfreqs + 1); // (float *) malloc0 ((nfreqs + 1) * sizeof (float));
G.resize(nfreqs + 1); // (float *) malloc0 ((nfreqs + 1) * sizeof (float));
F.resize(nfreqs + 1);
G.resize(nfreqs + 1);
F[1] = 150.0;
F[2] = 400.0;
F[3] = 1500.0;
@ -358,16 +364,15 @@ void EQP::setGrphEQ(int *rxeq)
ctfmode = 0;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
void EQP::setGrphEQ10(int *rxeq)
void EQP::setGrphEQ10(const int *rxeq)
{ // ten band equalizer (legacy compatibility)
float* impulse;
int i;
nfreqs = 10;
F.resize(nfreqs + 1); // (float *) malloc0 ((nfreqs + 1) * sizeof (float));
G.resize(nfreqs + 1); // (float *) malloc0 ((nfreqs + 1) * sizeof (float));
F.resize(nfreqs + 1);
G.resize(nfreqs + 1);
F[1] = 32.0;
F[2] = 63.0;
F[3] = 125.0;
@ -378,13 +383,12 @@ void EQP::setGrphEQ10(int *rxeq)
F[8] = 4000.0;
F[9] = 8000.0;
F[10] = 16000.0;
for (i = 0; i <= nfreqs; i++)
for (int i = 0; i <= nfreqs; i++)
G[i] = (float)rxeq[i];
ctfmode = 0;
impulse = eq_impulse (nc, nfreqs, F.data(), G.data(), samplerate, 1.0 / (2.0 * size), ctfmode, wintype);
// print_impulse ("rxeq.txt", nc, impulse, 1, 0);
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
} // namespace WDSP

View File

@ -89,10 +89,10 @@ public:
void setProfile(int nfreqs, const float* F, const float* G);
void setCtfmode(int mode);
void setWintype(int wintype);
void setGrphEQ(int *rxeq);
void setGrphEQ10(int *rxeq);
void setGrphEQ(const int *rxeq);
void setGrphEQ10(const int *rxeq);
static float* eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate, double scale, int ctfmode, int wintype);
static float* eq_impulse (int N, int nfreqs, const float* F, const float* G, double samplerate, double scale, int ctfmode, int wintype);
private:
static int fEQcompare (const void * a, const void * b);

View File

@ -25,6 +25,8 @@ warren@wpratt.com
*/
#include <array>
#include "comm.hpp"
#include "fircore.hpp"
#include "fcurve.hpp"
@ -91,8 +93,8 @@ void FMD::calc()
void FMD::decalc()
{
delete (plim);
delete (sntch);
delete plim;
delete sntch;
}
FMD::FMD(
@ -144,14 +146,24 @@ FMD::FMD(
float* impulse;
calc();
// de-emphasis filter
audio.resize(size * 2); // (float *) malloc0 (size * sizeof (complex));
impulse = FCurve::fc_impulse (nc_de, f_low, f_high, +20.0 * log10(f_high / f_low), 0.0, 1, rate, 1.0 / (2.0 * size), 0, 0);
audio.resize(size * 2);
impulse = FCurve::fc_impulse (
nc_de,
(float) f_low,
(float) f_high,
(float) (+20.0 * log10(f_high / f_low)),
0.0, 1,
(float) rate,
(float) (1.0 / (2.0 * size)),
0,
0
);
pde = FIRCORE::create_fircore (size, audio.data(), out, nc_de, mp_de, impulse);
delete[] (impulse);
delete[] impulse;
// audio filter
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);
delete[] impulse;
}
FMD::~FMD()
@ -179,8 +191,11 @@ void FMD::execute()
if (run)
{
int i;
double det, del_out;
double vco[2], corr[2];
double det;
double del_out;
std::array<double, 2> vco;
std::array<double, 2> corr;
for (i = 0; i < size; i++)
{
// pll
@ -200,7 +215,7 @@ void FMD::execute()
while (phs < 0.0) phs += TWOPI;
// dc removal, gain, & demod output
fmdc = mtau * fmdc + onem_mtau * fil_out;
audio[2 * i + 0] = again * (fil_out - fmdc);
audio[2 * i + 0] = (float) (again * (fil_out - fmdc));
audio[2 * i + 1] = audio[2 * i + 0];
}
// de-emphasis
@ -212,7 +227,7 @@ void FMD::execute()
if (lim_run)
{
for (i = 0; i < 2 * size; i++)
out[i] *= lim_pre_gain;
out[i] *= (float) lim_pre_gain;
plim->execute();
}
}
@ -238,13 +253,24 @@ void FMD::setSamplerate(int _rate)
rate = _rate;
calc();
// de-emphasis filter
impulse = FCurve::fc_impulse (nc_de, f_low, f_high, +20.0 * log10(f_high / f_low), 0.0, 1, rate, 1.0 / (2.0 * size), 0, 0);
impulse = FCurve::fc_impulse (
nc_de,
(float) f_low,
(float) f_high,
(float) (+20.0 * log10(f_high / f_low)),
0.0,
1,
(float) rate,
(float) (1.0 / (2.0 * size)),
0,
0
);
FIRCORE::setImpulse_fircore (pde, impulse, 1);
delete[] (impulse);
delete[] impulse;
// audio filter
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);
delete[] impulse;
plim->setSamplerate((int) rate);
}
@ -254,17 +280,28 @@ void FMD::setSize(int _size)
decalc();
size = _size;
calc();
audio.resize(size * 2); // (float *) malloc0 (size * sizeof (complex));
audio.resize(size * 2);
// de-emphasis filter
FIRCORE::destroy_fircore (pde);
impulse = FCurve::fc_impulse (nc_de, f_low, f_high, +20.0 * log10(f_high / f_low), 0.0, 1, rate, 1.0 / (2.0 * size), 0, 0);
impulse = FCurve::fc_impulse (
nc_de,
(float) f_low,
(float) f_high,
(float) (+20.0 * log10(f_high / f_low)),
0.0,
1,
(float) rate,
(float) (1.0 / (2.0 * size)),
0,
0
);
pde = FIRCORE::create_fircore (size, audio.data(), out, nc_de, mp_de, impulse);
delete[] (impulse);
delete[] impulse;
// audio filter
FIRCORE::destroy_fircore (paud);
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);
delete[] impulse;
plim->setSize(size);
}
@ -286,9 +323,9 @@ void FMD::setCTCSSFreq(double freq)
sntch->setFreq(ctcss_freq);
}
void FMD::setCTCSSRun(int run)
void FMD::setCTCSSRun(int _run)
{
sntch_run = run;
sntch_run = _run;
sntch->setRun(sntch_run);
}
@ -299,9 +336,20 @@ void FMD::setNCde(int nc)
if (nc_de != nc)
{
nc_de = nc;
impulse = FCurve::fc_impulse (nc_de, f_low, f_high, +20.0 * log10(f_high / f_low), 0.0, 1, rate, 1.0 / (2.0 * size), 0, 0);
impulse = FCurve::fc_impulse (
nc_de,
(float) f_low,
(float) f_high,
(float) (+20.0 * log10(f_high / f_low)),
0.0,
1,
(float) rate,
(float) (1.0 / (2.0 * size)),
0,
0
);
FIRCORE::setNc_fircore (pde, nc_de, impulse);
delete[] (impulse);
delete[] impulse;
}
}
@ -323,7 +371,7 @@ void FMD::setNCaud(int nc)
nc_aud = nc;
impulse = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size));
FIRCORE::setNc_fircore (paud, nc_aud, impulse);
delete[] (impulse);
delete[] impulse;
}
}
@ -336,10 +384,10 @@ void FMD::setMPaud(int mp)
}
}
void FMD::setLimRun(int run)
void FMD::setLimRun(int _run)
{
if (lim_run != run) {
lim_run = run;
if (lim_run != _run) {
lim_run = _run;
}
}
@ -364,13 +412,24 @@ void FMD::setAFFilter(double low, double high)
f_low = low;
f_high = high;
// de-emphasis filter
impulse = FCurve::fc_impulse (nc_de, f_low, f_high, +20.0 * log10(f_high / f_low), 0.0, 1, rate, 1.0 / (2.0 * size), 0, 0);
impulse = FCurve::fc_impulse (
nc_de,
(float) f_low,
(float) f_high,
(float) (+20.0 * log10(f_high / f_low)),
0.0,
1,
(float) rate,
(float) (1.0 / (2.0 * size)),
0,
0
);
FIRCORE::setImpulse_fircore (pde, impulse, 1);
delete[] (impulse);
delete[] impulse;
// audio filter
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);
delete[] impulse;
}
}

View File

@ -34,22 +34,23 @@ namespace WDSP {
void FMSQ::calc()
{
double delta, theta;
double delta;
double theta;
float* impulse;
int i;
// noise filter
noise.resize(2 * size * 2); // (float *)malloc0(2 * size * sizeof(complex));
noise.resize(2 * size * 2);
F[0] = 0.0;
F[1] = fc;
F[2] = *pllpole;
F[1] = (float) fc;
F[2] = (float) *pllpole;
F[3] = 20000.0;
G[0] = 0.0;
G[1] = 0.0;
G[2] = 3.0;
G[3] = +20.0 * log10(20000.0 / *pllpole);
G[3] = (float) (+20.0 * log10(20000.0 / *pllpole));
impulse = EQP::eq_impulse (nc, 3, F.data(), G.data(), rate, 1.0 / (2.0 * size), 0, 0);
p = FIRCORE::create_fircore (size, trigger, noise.data(), nc, mp, impulse);
delete[] (impulse);
delete[] impulse;
// noise averaging
avm = exp(-1.0 / (rate * avtau));
onem_avm = 1.0 - avm;
@ -60,8 +61,8 @@ void FMSQ::calc()
// level change
ntup = (int)(tup * rate);
ntdown = (int)(tdown * rate);
cup.resize(ntup + 1); // (float *)malloc0 ((ntup + 1) * sizeof(float));
cdown.resize(ntdown + 1); //(float *)malloc0 ((ntdown + 1) * sizeof(float));
cup.resize(ntup + 1);
cdown.resize(ntdown + 1);
delta = PI / (double) ntup;
theta = 0.0;
@ -80,7 +81,7 @@ void FMSQ::calc()
theta += delta;
}
// control
state = 0;
state = FMSQState::MUTED;
ready = 0;
ramp = 0.0;
rstep = 1.0 / rate;
@ -145,29 +146,20 @@ void FMSQ::flush()
FIRCORE::flush_fircore (p);
avnoise = 100.0;
longnoise = 1.0;
state = 0;
state = FMSQState::MUTED;
ready = 0;
ramp = 0.0;
}
enum _fmsqstate
{
MUTED,
INCREASE,
UNMUTED,
TAIL,
DECREASE
};
void FMSQ::execute()
{
if (run)
{
int i;
double _noise, lnlimit;
double _noise;
double lnlimit;
FIRCORE::xfircore (p);
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
double noise0 = noise[2 * i + 0];
double noise1 = noise[2 * i + 1];
@ -183,10 +175,10 @@ void FMSQ::execute()
switch (state)
{
case MUTED:
case FMSQState::MUTED:
if (avnoise < unmute_thresh && ready)
{
state = INCREASE;
state = FMSQState::INCREASE;
count = ntup;
}
@ -195,19 +187,19 @@ void FMSQ::execute()
break;
case INCREASE:
outsig[2 * i + 0] = insig[2 * i + 0] * cup[ntup - count];
outsig[2 * i + 1] = insig[2 * i + 1] * cup[ntup - count];
case FMSQState::INCREASE:
outsig[2 * i + 0] = (float) (insig[2 * i + 0] * cup[ntup - count]);
outsig[2 * i + 1] = (float) (insig[2 * i + 1] * cup[ntup - count]);
if (count-- == 0)
state = UNMUTED;
state = FMSQState::UNMUTED;
break;
case UNMUTED:
case FMSQState::UNMUTED:
if (avnoise > tail_thresh)
{
state = TAIL;
state = FMSQState::TAIL;
if ((lnlimit = longnoise) > 1.0)
lnlimit = 1.0;
@ -220,28 +212,28 @@ void FMSQ::execute()
break;
case TAIL:
case FMSQState::TAIL:
outsig[2 * i + 0] = insig[2 * i + 0];
outsig[2 * i + 1] = insig[2 * i + 1];
if (avnoise < unmute_thresh)
{
state = UNMUTED;
state = FMSQState::UNMUTED;
}
else if (count-- == 0)
{
state = DECREASE;
state = FMSQState::DECREASE;
count = ntdown;
}
break;
case DECREASE:
outsig[2 * i + 0] = insig[2 * i + 0] * cdown[ntdown - count];
outsig[2 * i + 1] = insig[2 * i + 1] * cdown[ntdown - count];
case FMSQState::DECREASE:
outsig[2 * i + 0] = (float) (insig[2 * i + 0] * cdown[ntdown - count]);
outsig[2 * i + 1] = (float) (insig[2 * i + 1] * cdown[ntdown - count]);
if (count-- == 0)
state = MUTED;
state = FMSQState::MUTED;
break;
}
@ -301,7 +293,7 @@ void FMSQ::setNC(int _nc)
nc = _nc;
impulse = EQP::eq_impulse (nc, 3, F.data(), G.data(), rate, 1.0 / (2.0 * size), 0, 0);
FIRCORE::setNc_fircore (p, nc, impulse);
delete[] (impulse);
delete[] impulse;
}
}

View File

@ -40,6 +40,15 @@ class FIRCORE;
class WDSP_API FMSQ
{
public:
enum class FMSQState
{
MUTED,
INCREASE,
UNMUTED,
TAIL,
DECREASE
};
int run; // 0 if squelch system is OFF; 1 if it's ON
int size; // size of input/output buffers
float* insig; // squelch input signal buffer
@ -59,7 +68,7 @@ public:
double longavm;
double onem_longavm;
double longnoise;
int state; // state machine control
FMSQState state; // state machine control
int count;
double tup;
double tdown;

View File

@ -78,8 +78,8 @@ void GEN::calc_triangle()
void GEN::calc_pulse ()
{
int i;
float delta, theta;
double delta;
double theta;
pulse.pperiod = 1.0 / pulse.pf;
pulse.tphs = 0.0;
pulse.tdelta = TWOPI * pulse.tf / rate;
@ -93,11 +93,11 @@ void GEN::calc_pulse ()
pulse.pnoff = 0;
pulse.pcount = pulse.pnoff;
pulse.state = 0;
pulse.ctrans = new float[pulse.pntrans + 1]; // (float *) malloc0 ((pulse.pntrans + 1) * sizeof (float));
pulse.state = PState::OFF;
pulse.ctrans = new double[pulse.pntrans + 1];
delta = PI / (float)pulse.pntrans;
theta = 0.0;
for (i = 0; i <= pulse.pntrans; i++)
for (int i = 0; i <= pulse.pntrans; i++)
{
pulse.ctrans[i] = 0.5 * (1.0 - cos (theta));
theta += delta;
@ -143,7 +143,7 @@ GEN::GEN(
tt.f1 = + 900.0;
tt.f2 = + 1700.0;
// noise
srand ((unsigned int) time (0));
srand ((unsigned int) time (nullptr));
noise.mag = 1.0;
// sweep
sweep.mag = 1.0;
@ -172,17 +172,9 @@ GEN::~GEN()
void GEN::flush()
{
pulse.state = 0;
pulse.state = PState::OFF;
}
enum pstate
{
OFF,
UP,
ON,
DOWN
};
void GEN::execute()
{
if (run)
@ -191,14 +183,14 @@ void GEN::execute()
{
case 0: // tone
{
int i;
float t1, t2;
float cosphase = cos (tone.phs);
float sinphase = sin (tone.phs);
for (i = 0; i < size; i++)
double t1;
double t2;
double cosphase = cos (tone.phs);
double sinphase = sin (tone.phs);
for (int i = 0; i < size; i++)
{
out[2 * i + 0] = + tone.mag * cosphase;
out[2 * i + 1] = - tone.mag * sinphase;
out[2 * i + 0] = (float) (+ tone.mag * cosphase);
out[2 * i + 1] = (float) (- tone.mag * sinphase);
t1 = cosphase;
t2 = sinphase;
cosphase = t1 * tone.cosdelta - t2 * tone.sindelta;
@ -211,16 +203,16 @@ void GEN::execute()
}
case 1: // two-tone
{
int i;
float tcos, tsin;
float cosphs1 = cos (tt.phs1);
float sinphs1 = sin (tt.phs1);
float cosphs2 = cos (tt.phs2);
float sinphs2 = sin (tt.phs2);
for (i = 0; i < size; i++)
double tcos;
double tsin;
double cosphs1 = cos (tt.phs1);
double sinphs1 = sin (tt.phs1);
double cosphs2 = cos (tt.phs2);
double sinphs2 = sin (tt.phs2);
for (int i = 0; i < size; i++)
{
out[2 * i + 0] = + tt.mag1 * cosphs1 + tt.mag2 * cosphs2;
out[2 * i + 1] = - tt.mag1 * sinphs1 - tt.mag2 * sinphs2;
out[2 * i + 0] = (float) (+ tt.mag1 * cosphs1 + tt.mag2 * cosphs2);
out[2 * i + 1] = (float) (- tt.mag1 * sinphs1 - tt.mag2 * sinphs2);
tcos = cosphs1;
tsin = sinphs1;
cosphs1 = tcos * tt.cosdelta1 - tsin * tt.sindelta1;
@ -240,29 +232,30 @@ void GEN::execute()
}
case 2: // noise
{
int i;
float r1, r2, c, rad;
for (i = 0; i < size; i++)
double r1;
double r2;
double c;
double rad;
for (int i = 0; i < size; i++)
{
do
{
r1 = 2.0 * (float)rand() / (float)RAND_MAX - 1.0;
r2 = 2.0 * (float)rand() / (float)RAND_MAX - 1.0;
r1 = 2.0 * (double)rand() / (double)RAND_MAX - 1.0;
r2 = 2.0 * (double)rand() / (double)RAND_MAX - 1.0;
c = r1 * r1 + r2 * r2;
} while (c >= 1.0);
rad = sqrt (-2.0 * log (c) / c);
out[2 * i + 0] = noise.mag * rad * r1;
out[2 * i + 1] = noise.mag * rad * r2;
out[2 * i + 0] = (float) (noise.mag * rad * r1);
out[2 * i + 1] = (float) (noise.mag * rad * r2);
}
break;
}
case 3: // sweep
{
int i;
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
out[2 * i + 0] = + sweep.mag * cos(sweep.phs);
out[2 * i + 1] = - sweep.mag * sin(sweep.phs);
out[2 * i + 0] = (float) (+ sweep.mag * cos(sweep.phs));
out[2 * i + 1] = (float) (- sweep.mag * sin(sweep.phs));
sweep.phs += sweep.dphs;
sweep.dphs += sweep.d2phs;
if (sweep.phs >= TWOPI) sweep.phs -= TWOPI;
@ -274,11 +267,10 @@ void GEN::execute()
}
case 4: // sawtooth (audio only)
{
int i;
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
if (saw.t > saw.period) saw.t -= saw.period;
out[2 * i + 0] = saw.mag * (saw.t * saw.f - 1.0);
out[2 * i + 0] = (float) (saw.mag * (saw.t * saw.f - 1.0));
out[2 * i + 1] = 0.0;
saw.t += saw.delta;
}
@ -286,13 +278,12 @@ void GEN::execute()
break;
case 5: // triangle (audio only)
{
int i;
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
if (tri.t > tri.period) tri.t1 = tri.t -= tri.period;
if (tri.t > tri.half) tri.t1 -= tri.delta;
else tri.t1 += tri.delta;
out[2 * i + 0] = tri.mag * (4.0 * tri.t1 * tri.f - 1.0);
out[2 * i + 0] = (float) (tri.mag * (4.0 * tri.t1 * tri.f - 1.0));
out[2 * i + 1] = 0.0;
tri.t += tri.delta;
}
@ -300,44 +291,44 @@ void GEN::execute()
break;
case 6: // pulse (audio only)
{
int i;
float t1, t2;
float cosphase = cos (pulse.tphs);
float sinphase = sin (pulse.tphs);
for (i = 0; i < size; i++)
double t1;
double t2;
double cosphase = cos (pulse.tphs);
double sinphase = sin (pulse.tphs);
for (int i = 0; i < size; i++)
{
if (pulse.pnoff != 0)
switch (pulse.state)
{
case OFF:
case PState::OFF:
out[2 * i + 0] = 0.0;
if (--pulse.pcount == 0)
{
pulse.state = UP;
pulse.state = PState::UP;
pulse.pcount = pulse.pntrans;
}
break;
case UP:
out[2 * i + 0] = pulse.mag * cosphase * pulse.ctrans[pulse.pntrans - pulse.pcount];
case PState::UP:
out[2 * i + 0] = (float) (pulse.mag * cosphase * pulse.ctrans[pulse.pntrans - pulse.pcount]);
if (--pulse.pcount == 0)
{
pulse.state = ON;
pulse.state = PState::ON;
pulse.pcount = pulse.pnon;
}
break;
case ON:
out[2 * i + 0] = pulse.mag * cosphase;
case PState::ON:
out[2 * i + 0] = (float) (pulse.mag * cosphase);
if (--pulse.pcount == 0)
{
pulse.state = DOWN;
pulse.state = PState::DOWN;
pulse.pcount = pulse.pntrans;
}
break;
case DOWN:
out[2 * i + 0] = pulse.mag * cosphase * pulse.ctrans[pulse.pcount];
case PState::DOWN:
out[2 * i + 0] = (float) (pulse.mag * cosphase * pulse.ctrans[pulse.pcount]);
if (--pulse.pcount == 0)
{
pulse.state = OFF;
pulse.state = PState::OFF;
pulse.pcount = pulse.pnoff;
}
break;
@ -432,9 +423,9 @@ void GEN::SetPreSweepFreq(float freq1, float freq2)
calc_sweep();
}
void GEN::SetPreSweepRate(float rate)
void GEN::SetPreSweepRate(float _rate)
{
sweep.sweeprate = rate;
sweep.sweeprate = _rate;
calc_sweep();
}

View File

@ -37,88 +37,103 @@ class TXA;
class WDSP_API GEN
{
public:
enum class PState
{
OFF,
UP,
ON,
DOWN
};
int run; // run
int size; // number of samples per buffer
float* in; // input buffer (retained in case I want to mix in a generated signal)
float* out; // output buffer
float rate; // sample rate
double rate; // sample rate
int mode;
struct _tone
{
float mag;
float freq;
float phs;
float delta;
float cosdelta;
float sindelta;
} tone;
double mag;
double freq;
double phs;
double delta;
double cosdelta;
double sindelta;
};
_tone tone;
struct _tt
{
float mag1;
float mag2;
float f1;
float f2;
float phs1;
float phs2;
float delta1;
float delta2;
float cosdelta1;
float cosdelta2;
float sindelta1;
float sindelta2;
} tt;
double mag1;
double mag2;
double f1;
double f2;
double phs1;
double phs2;
double delta1;
double delta2;
double cosdelta1;
double cosdelta2;
double sindelta1;
double sindelta2;
};
_tt tt;
struct _noise
{
float mag;
} noise;
double mag;
};
_noise noise;
struct _sweep
{
float mag;
float f1;
float f2;
float sweeprate;
float phs;
float dphs;
float d2phs;
float dphsmax;
} sweep;
double mag;
double f1;
double f2;
double sweeprate;
double phs;
double dphs;
double d2phs;
double dphsmax;
};
_sweep sweep;
struct _saw
{
float mag;
float f;
float period;
float delta;
float t;
} saw;
double mag;
double f;
double period;
double delta;
double t;
};
_saw saw;
struct _tri
{
float mag;
float f;
float period;
float half;
float delta;
float t;
float t1;
} tri;
double mag;
double f;
double period;
double half;
double delta;
double t;
double t1;
};
_tri tri;
struct _pulse
{
float mag;
float pf;
float pdutycycle;
float ptranstime;
float* ctrans;
double mag;
double pf;
double pdutycycle;
double ptranstime;
double* ctrans;
int pcount;
int pnon;
int pntrans;
int pnoff;
float pperiod;
float tf;
float tphs;
float tdelta;
float tcosdelta;
float tsindelta;
int state;
} pulse;
double pperiod;
double tf;
double tphs;
double tdelta;
double tcosdelta;
double tsindelta;
PState state;
};
_pulse pulse;
GEN(
int run,

View File

@ -51,20 +51,20 @@ METER::METER(
int _enum_pk,
int _enum_gain,
double* _pgain
)
) :
run(_run),
prun(_prun),
size(_size),
buff(_buff),
rate((double) _rate),
tau_average(_tau_av),
tau_peak_decay(_tau_decay),
result(_result),
enum_av(_enum_av),
enum_pk(_enum_pk),
enum_gain(_enum_gain),
pgain(_pgain)
{
run = _run;
prun = _prun;
size = _size;
buff = _buff;
rate = (double) _rate;
tau_average = _tau_av;
tau_peak_decay = _tau_decay;
result = _result;
enum_av = _enum_av;
enum_pk = _enum_pk;
enum_gain = _enum_gain;
pgain = _pgain;
calc();
}
@ -75,7 +75,7 @@ void METER::flush()
result[enum_av] = -100.0;
result[enum_pk] = -100.0;
if ((pgain != 0) && (enum_gain >= 0))
if ((pgain != nullptr) && (enum_gain >= 0))
result[enum_gain] = 0.0;
}
@ -83,18 +83,17 @@ void METER::execute()
{
int srun;
if (prun != 0)
srun = *(prun);
if (prun != nullptr)
srun = *prun;
else
srun = 1;
if (run && srun)
{
int i;
double smag;
double np = 0.0;
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
double xr = buff[2 * i + 0];
double xi = buff[2 * i + 1];
@ -112,7 +111,7 @@ void METER::execute()
result[enum_av] = 10.0 * MemLog::mlog10 (avg <= 0 ? 1.0e-20 : avg);
result[enum_pk] = 10.0 * MemLog::mlog10 (peak <= 0 ? 1.0e-20 : peak);
if ((pgain != 0) && (enum_gain >= 0))
if ((pgain != nullptr) && (enum_gain >= 0))
result[enum_gain] = 20.0 * MemLog::mlog10 (*pgain <= 0 ? 1.0e-20 : *pgain);
}
else
@ -150,7 +149,7 @@ void METER::setSize(int _size)
* *
********************************************************************************************************/
double METER::getMeter(int mt)
double METER::getMeter(int mt) const
{
return result[mt];
}

View File

@ -75,7 +75,7 @@ public:
void setBuffers(float* in);
void setSamplerate(int rate);
void setSize(int size);
double getMeter(int mt);
double getMeter(int mt) const;
private:
void calc();

View File

@ -39,8 +39,8 @@ namespace WDSP {
void MPEAK::calc()
{
tmp.resize(size * 2); // (float *) malloc0 (size * sizeof (complex));
mix.resize(size * 2); // (float *) malloc0 (size * sizeof (complex));
tmp.resize(size * 2);
mix.resize(size * 2);
for (int i = 0; i < npeaks; i++)
{
pfil[i] = new SPEAK(
@ -85,15 +85,15 @@ MPEAK::MPEAK(
rate = _rate;
npeaks = _npeaks;
nstages = _nstages;
enable.resize(npeaks); // (int *) malloc0 (npeaks * sizeof (int));
f.resize(npeaks); // (float *) malloc0 (npeaks * sizeof (float));
bw.resize(npeaks); // (float *) malloc0 (npeaks * sizeof (float));
gain.resize(npeaks); // (float *) malloc0 (npeaks * sizeof (float));
enable.resize(npeaks);
f.resize(npeaks);
bw.resize(npeaks);
gain.resize(npeaks);
std::copy(_enable, _enable + npeaks, enable.begin());
std::copy(_f, _f + npeaks, f.begin());
std::copy(_bw, _bw + npeaks, bw.begin());
std::copy(_gain, _gain + npeaks, gain.begin());
pfil.resize(npeaks); // (SPEAK *) malloc0 (npeaks * sizeof (SPEAK));
pfil.resize(npeaks);
calc();
}

View File

@ -25,6 +25,8 @@ warren@wpratt.com
*/
#include <array>
#include "comm.hpp"
#include "fir.hpp"
#include "fircore.hpp"
@ -44,16 +46,17 @@ NOTCHDB::NOTCHDB(int _master_run, int _maxnotches)
master_run = _master_run;
maxnotches = _maxnotches;
nn = 0;
fcenter.resize(maxnotches); // (float *) malloc0 (maxnotches * sizeof (float));
fwidth.resize(maxnotches); // (float *) malloc0 (maxnotches * sizeof (float));
nlow.resize(maxnotches); // (float *) malloc0 (maxnotches * sizeof (float));
nhigh.resize(maxnotches); // (float *) malloc0 (maxnotches * sizeof (float));
active.resize(maxnotches); // (int *) malloc0 (maxnotches * sizeof (int ));
fcenter.resize(maxnotches);
fwidth.resize(maxnotches);
nlow.resize(maxnotches);
nhigh.resize(maxnotches);
active.resize(maxnotches);
}
int NOTCHDB::addNotch(int notch, double _fcenter, double _fwidth, int _active)
{
int i, j;
int i;
int j;
int rval;
if (notch <= nn && nn < maxnotches)
@ -104,7 +107,8 @@ int NOTCHDB::getNotch(int _notch, double* _fcenter, double* _fwidth, int* _activ
int NOTCHDB::deleteNotch(int _notch)
{
int i, j;
int i;
int j;
int rval;
if (_notch < nn)
@ -143,7 +147,7 @@ int NOTCHDB::editNotch(int _notch, double _fcenter, double _fwidth, int _active)
return rval;
}
void NOTCHDB::getNumNotches(int* _nnotches)
void NOTCHDB::getNumNotches(int* _nnotches) const
{
*_nnotches = nn;
}
@ -154,25 +158,24 @@ void NOTCHDB::getNumNotches(int* _nnotches)
* *
********************************************************************************************************/
float* NBP::fir_mbandpass (int N, int nbp, double* flow, double* fhigh, double rate, double scale, int wintype)
float* NBP::fir_mbandpass (int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype)
{
int i, k;
float* impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
float* imp;
for (k = 0; k < nbp; k++)
auto* impulse = new float[N * 2];
std::fill(impulse, impulse + N*2, 0);
for (int k = 0; k < nbp; k++)
{
imp = FIR::fir_bandpass (N, flow[k], fhigh[k], rate, wintype, 1, scale);
for (i = 0; i < N; i++)
float* imp = FIR::fir_bandpass (N, flow[k], fhigh[k], rate, wintype, 1, scale);
for (int i = 0; i < N; i++)
{
impulse[2 * i + 0] += imp[2 * i + 0];
impulse[2 * i + 1] += imp[2 * i + 1];
}
delete[] (imp);
delete[] imp;
}
return impulse;
}
double NBP::min_notch_width()
double NBP::min_notch_width() const
{
double min_width;
switch (wintype)
@ -183,6 +186,8 @@ double NBP::min_notch_width()
case 1:
min_width = 2200.0 / (nc / 256) * (rate / 48000);
break;
default:
min_width = 0;
}
return min_width;
}
@ -204,10 +209,12 @@ int NBP::make_nbp (
)
{
int nbp;
int nnbp, adds;
int i, j, k;
double nl, nh;
int* del = new int[1024]; // (int *) malloc0 (1024 * sizeof (int));
int nnbp;
int adds;
int i;
double nl;
double nh;
std::array<int, 1024> del;
if (fhigh > flow)
{
bplow[0] = flow;
@ -217,11 +224,10 @@ int NBP::make_nbp (
else
{
nbp = 0;
delete[] del;
return nbp;
}
*havnotch = 0;
for (k = 0; k < nn; k++)
for (int k = 0; k < nn; k++)
{
if (autoincr && width[k] < minwidth)
{
@ -270,7 +276,7 @@ int NBP::make_nbp (
if (del[i] == 1)
{
nnbp--;
for (j = i; j < nnbp; j++)
for (int j = i; j < nnbp; j++)
{
bplow[j] = bplow[j + 1];
bphigh[j] = bphigh[j + 1];
@ -281,14 +287,13 @@ int NBP::make_nbp (
nbp = nnbp;
}
}
delete[] (del);
return nbp;
}
void NBP::calc_lightweight()
{ // calculate and set new impulse response; used when changing tune freq or shift freq
int i;
double fl, fh;
double fl;
double fh;
double offset;
NOTCHDB *b = notchdb;
if (fnfrun)
@ -314,7 +319,7 @@ void NBP::calc_lightweight()
// when tuning, no need to recalc filter if there were not and are not any notches in passband
if (hadnotch || havnotch)
{
for (i = 0; i < numpb; i++)
for (int i = 0; i < numpb; i++)
{
bplow[i] -= offset;
bphigh[i] -= offset;
@ -330,7 +335,7 @@ void NBP::calc_lightweight()
);
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
// print_impulse ("nbp.txt", size + 1, impulse, 1, 0);
delete[](impulse);
delete[] impulse;
}
hadnotch = havnotch;
}
@ -340,8 +345,8 @@ void NBP::calc_lightweight()
void NBP::calc_impulse ()
{ // calculates impulse response; for create_fircore() and parameter changes
int i;
float fl, fh;
double fl;
double fh;
double offset;
NOTCHDB *b = notchdb;
@ -365,7 +370,7 @@ void NBP::calc_impulse ()
bphigh,
&havnotch
);
for (i = 0; i < numpb; i++)
for (int i = 0; i < numpb; i++)
{
bplow[i] -= offset;
bphigh[i] -= offset;
@ -429,12 +434,12 @@ NBP::NBP(
maxpb(_maxpb),
notchdb(_notchdb)
{
bplow.resize(maxpb); // (float *) malloc0 (maxpb * sizeof (float));
bphigh.resize(maxpb); // (float *) malloc0 (maxpb * sizeof (float));
bplow.resize(maxpb);
bphigh.resize(maxpb);
calc_impulse ();
fircore = FIRCORE::create_fircore (size, in, out, nc, mp, impulse);
// print_impulse ("nbp.txt", size + 1, impulse, 1, 0);
delete[](impulse);
delete[]impulse;
}
NBP::~NBP()
@ -467,7 +472,7 @@ void NBP::setSamplerate(int _rate)
rate = _rate;
calc_impulse ();
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
void NBP::setSize(int _size)
@ -477,14 +482,14 @@ void NBP::setSize(int _size)
FIRCORE::setSize_fircore (fircore, size);
calc_impulse ();
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
void NBP::setNc()
{
calc_impulse();
FIRCORE::setNc_fircore (fircore, nc, impulse);
delete[] (impulse);
delete[] impulse;
}
void NBP::setMp()
@ -513,7 +518,7 @@ void NBP::SetFreqs(double _flow, double _fhigh)
fhigh = _fhigh;
calc_impulse();
FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (impulse);
delete[] impulse;
}
}
@ -536,7 +541,7 @@ void NBP::SetMP(int _mp)
}
}
void NBP::GetMinNotchWidth(double* minwidth)
void NBP::GetMinNotchWidth(double* minwidth) const
{
*minwidth = min_notch_width();
}

View File

@ -59,7 +59,7 @@ public:
int getNotch (int notch, double* fcenter, double* fwidth, int* active);
int deleteNotch (int notch);
int editNotch (int notch, double fcenter, double fwidth, int active);
void getNumNotches (int* nnotches);
void getNumNotches (int* nnotches) const;
};
@ -125,12 +125,12 @@ public:
void SetFreqs(double flow, double fhigh);
void SetNC(int nc);
void SetMP(int mp);
void GetMinNotchWidth(double* minwidth);
void GetMinNotchWidth(double* minwidth) const;
void calc_lightweight();
private:
static float* fir_mbandpass (int N, int nbp, double* flow, double* fhigh, double rate, double scale, int wintype);
double min_notch_width ();
static float* fir_mbandpass (int N, int nbp, const double* flow, const double* fhigh, double rate, double scale, int wintype);
double min_notch_width () const;
static int make_nbp (
int nn,
std::vector<int>& active,

View File

@ -150,8 +150,10 @@ void NOB::execute()
double mag;
int bf_idx;
int ff_idx;
int lidx, tidx;
int i, j, k;
int lidx;
int tidx;
int j;
int k;
int bfboutidx;
int ffboutidx;
int hcount;
@ -161,7 +163,7 @@ void NOB::execute()
if (run)
{
for (i = 0; i < buffsize; i++)
for (int i = 0; i < buffsize; i++)
{
dline[2 * in_idx + 0] = in[2 * i + 0];
dline[2 * in_idx + 1] = in[2 * i + 1];
@ -189,8 +191,8 @@ void NOB::execute()
{
case 0: // normal output & impulse setup
{
out[2 * i + 0] = dline[2 * out_idx + 0];
out[2 * i + 1] = dline[2 * out_idx + 1];
out[2 * i + 0] = (float) (dline[2 * out_idx + 0]);
out[2 * i + 1] = (float) (dline[2 * out_idx + 1]);
Ilast = dline[2 * out_idx + 0];
Qlast = dline[2 * out_idx + 1];
@ -210,7 +212,6 @@ void NOB::execute()
do
{
len = 0;
hcount = 0;
while ((imp[tidx] > 0 || hcount > 0) && blank_count < max_imp_seq)
@ -314,7 +315,7 @@ void NOB::execute()
switch (mode)
{
case 0: // zero
default: // zero
deltaI = 0.0;
deltaQ = 0.0;
I = 0.0;
@ -367,8 +368,8 @@ void NOB::execute()
case 1: // slew output in advance of blanking period
{
scale = 0.5 + awave[time];
out[2 * i + 0] = Ilast * scale + (1.0 - scale) * I;
out[2 * i + 1] = Qlast * scale + (1.0 - scale) * Q;
out[2 * i + 0] = (float) (Ilast * scale + (1.0 - scale) * I);
out[2 * i + 1] = (float) (Qlast * scale + (1.0 - scale) * Q);
if (++time == adv_slew_count)
{
@ -385,8 +386,8 @@ void NOB::execute()
case 2: // initial advance period
{
out[2 * i + 0] = I;
out[2 * i + 1] = Q;
out[2 * i + 0] = (float) I;
out[2 * i + 1] = (float) Q;
I += deltaI;
Q += deltaQ;
@ -401,8 +402,8 @@ void NOB::execute()
case 3: // impulse & hang period
{
out[2 * i + 0] = I;
out[2 * i + 1] = Q;
out[2 * i + 0] = (float) I;
out[2 * i + 1] = (float) Q;
I += deltaI;
Q += deltaQ;
@ -425,8 +426,8 @@ void NOB::execute()
case 4: // slew output after blanking period
{
scale = 0.5 - hwave[time];
out[2 * i + 0] = Inext * scale + (1.0 - scale) * I;
out[2 * i + 1] = Qnext * scale + (1.0 - scale) * Q;
out[2 * i + 0] = (float) (Inext * scale + (1.0 - scale) * I);
out[2 * i + 1] = (float) (Qnext * scale + (1.0 - scale) * Q);
if (++time == hang_slew_count)
state = 0;
@ -437,8 +438,8 @@ void NOB::execute()
case 5:
{
scale = 0.5 + awave[time];
out[2 * i + 0] = Ilast * scale;
out[2 * i + 1] = Qlast * scale;
out[2 * i + 0] = (float) (Ilast * scale);
out[2 * i + 1] = (float) (Qlast * scale);
if (++time == adv_slew_count)
{
@ -542,8 +543,8 @@ void NOB::execute()
case 9:
{
scale = 0.5 - hwave[time];
out[2 * i + 0] = Inext * scale;
out[2 * i + 1] = Qnext * scale;
out[2 * i + 0] = (float) (Inext * scale);
out[2 * i + 1] = (float) (Qnext * scale);
if (++time >= hang_slew_count)
{

View File

@ -55,24 +55,26 @@ PANEL::PANEL(
void PANEL::flush()
{
// There is no data to be reset internally
}
void PANEL::execute()
{
int i;
double I, Q;
double I;
double Q;
double gainI = gain1 * gain2I;
double gainQ = gain1 * gain2Q;
// inselect is either 0(neither), 1(Q), 2(I), or 3(both)
switch (copy)
{
case 0: // no copy
default: // 0 (default) no copy
for (i = 0; i < size; i++)
{
I = in[2 * i + 0] * (inselect >> 1);
Q = in[2 * i + 1] * (inselect & 1);
out[2 * i + 0] = gainI * I;
out[2 * i + 1] = gainQ * Q;
out[2 * i + 0] = (float) (gainI * I);
out[2 * i + 1] = (float) (gainQ * Q);
}
break;
case 1: // copy I to Q (then Q == I)
@ -80,17 +82,17 @@ void PANEL::execute()
{
I = in[2 * i + 0] * (inselect >> 1);
Q = I;
out[2 * i + 0] = gainI * I;
out[2 * i + 1] = gainQ * Q;
out[2 * i + 0] = (float) (gainI * I);
out[2 * i + 1] = (float) (gainQ * Q);
}
break;
case 2: // copy Q to I (then I == Q)
for (i = 0; i < size; i++)
{
Q = in[2 * i + 1] * (inselect & 1);
Q = in[2 * i + 1] * (inselect & 1);
I = Q;
out[2 * i + 0] = gainI * I;
out[2 * i + 1] = gainQ * Q;
out[2 * i + 0] = (float) (gainI * I);
out[2 * i + 1] = (float) (gainQ * Q);
}
break;
case 3: // reverse (I=>Q and Q=>I)
@ -98,8 +100,8 @@ void PANEL::execute()
{
Q = in[2 * i + 0] * (inselect >> 1);
I = in[2 * i + 1] * (inselect & 1);
out[2 * i + 0] = gainI * I;
out[2 * i + 1] = gainQ * Q;
out[2 * i + 0] = (float) (gainI * I);
out[2 * i + 1] = (float) (gainQ * Q);
}
break;
}
@ -113,6 +115,7 @@ void PANEL::setBuffers(float* _in, float* _out)
void PANEL::setSamplerate(int)
{
// There is no sample rate to be set for this component
}
void PANEL::setSize(int _size)
@ -149,21 +152,22 @@ void PANEL::setGain2(double _gainI, double _gainQ)
void PANEL::setPan(double _pan)
{
double gain1, gain2;
double _gain1;
double _gain2;
if (_pan <= 0.5)
{
gain1 = 1.0;
gain2 = sin (_pan * PI);
_gain1 = 1.0;
_gain2 = sin (_pan * PI);
}
else
{
gain1 = sin (_pan * PI);
gain2 = 1.0;
_gain1 = sin (_pan * PI);
_gain2 = 1.0;
}
gain2I = gain1;
gain2Q = gain2;
gain2I = _gain1;
gain2Q = _gain2;
}
void PANEL::setCopy(int _copy)

View File

@ -39,10 +39,10 @@ namespace WDSP {
void PHROT::calc()
{
double g;
x0.resize(nstages); // (float *) malloc0 (nstages * sizeof (float));
x1.resize(nstages); // (float *) malloc0 (nstages * sizeof (float));
y0.resize(nstages); // (float *) malloc0 (nstages * sizeof (float));
y1.resize(nstages); // (float *) malloc0 (nstages * sizeof (float));
x0.resize(nstages);
x1.resize(nstages);
y0.resize(nstages);
y1.resize(nstages);
g = tan (PI * fc / (float)rate);
b0 = (g - 1.0) / (g + 1.0);
b1 = 1.0;
@ -58,7 +58,6 @@ PHROT::PHROT(
double _fc,
int _nstages
) :
reverse(0),
run(_run),
size(_size),
in(_in),
@ -67,6 +66,7 @@ PHROT::PHROT(
fc(_fc),
nstages(_nstages)
{
reverse = 0;
calc();
}
@ -102,7 +102,7 @@ void PHROT::execute()
x1[n] = x0[n];
}
out[2 * i + 0] = y0[nstages - 1];
out[2 * i + 0] = (float) y0[nstages - 1];
}
}
else if (out != in)
@ -135,9 +135,9 @@ void PHROT::setSize(int _size)
* *
********************************************************************************************************/
void PHROT::setRun(int run)
void PHROT::setRun(int _run)
{
run = run;
run = _run;
if (run)
flush();

View File

@ -54,8 +54,13 @@ public:
double fc;
int nstages;
// normalized such that a0 = 1
double a1, b0, b1;
std::vector<double> x0, x1, y0, y1;
double a1;
double b0;
double b1;
std::vector<double> x0;
std::vector<double> x1;
std::vector<double> y0;
std::vector<double> y1;
PHROT(
int run,

View File

@ -39,11 +39,14 @@ namespace WDSP {
void RESAMPLE::calc()
{
int x, y, z;
int i, j, k;
int x;
int y;
int z;
int i;
int min_rate;
double full_rate;
double fc_norm_high, fc_norm_low;
double fc_norm_high;
double fc_norm_low;
float* impulse;
fc = fcin;
ncoef = ncoefin;
@ -84,22 +87,22 @@ void RESAMPLE::calc()
ncoef = (ncoef / L + 1) * L;
cpp = ncoef / L;
h.resize(ncoef); // (float *)malloc0(ncoef * sizeof(float));
h.resize(ncoef);
impulse = FIR::fir_bandpass(ncoef, fc_norm_low, fc_norm_high, 1.0, 1, 0, gain * (double)L);
i = 0;
for (j = 0; j < L; j++)
for (int j = 0; j < L; j++)
{
for (k = 0; k < ncoef; k += L)
for (int k = 0; k < ncoef; k += L)
h[i++] = impulse[j + k];
}
ringsize = cpp;
ring.resize(ringsize); // (float *)malloc0(ringsize * sizeof(complex));
ring.resize(ringsize);
idx_in = ringsize - 1;
phnum = 0;
delete[] (impulse);
delete[] impulse;
}
RESAMPLE::RESAMPLE (
@ -141,11 +144,12 @@ int RESAMPLE::execute()
if (run)
{
int i, j, n;
int n;
int idx_out;
double I, Q;
double I;
double Q;
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
ring[2 * idx_in + 0] = in[2 * i + 0];
ring[2 * idx_in + 1] = in[2 * i + 1];
@ -156,7 +160,7 @@ int RESAMPLE::execute()
Q = 0.0;
n = cpp * phnum;
for (j = 0; j < cpp; j++)
for (int j = 0; j < cpp; j++)
{
if ((idx_out = idx_in + j) >= ringsize)
idx_out -= ringsize;
@ -165,8 +169,8 @@ int RESAMPLE::execute()
Q += h[n + j] * ring[2 * idx_out + 1];
}
out[2 * outsamps + 0] = I;
out[2 * outsamps + 1] = Q;
out[2 * outsamps + 0] = (float) I;
out[2 * outsamps + 1] = (float) Q;
outsamps++;
phnum += M;
}
@ -231,25 +235,24 @@ void RESAMPLE::setBandwidth(double _fc_low, double _fc_high)
// exported calls
void* RESAMPLE::createV (int in_rate, int out_rate)
RESAMPLE* RESAMPLE::Create(int in_rate, int out_rate)
{
return (void *) new RESAMPLE(1, 0, 0, 0, in_rate, out_rate, 0.0, 0, 1.0);
return new RESAMPLE(1, 0, nullptr, nullptr, in_rate, out_rate, 0.0, 0, 1.0);
}
void RESAMPLE::executeV (float* input, float* output, int numsamps, int* outsamps, void* ptr)
void RESAMPLE::Execute(float* input, float* output, int numsamps, int* outsamps, RESAMPLE* ptr)
{
RESAMPLE *a = (RESAMPLE*) ptr;
a->in = input;
a->out = output;
a->size = numsamps;
*outsamps = a->execute();
ptr->in = input;
ptr->out = output;
ptr->size = numsamps;
*outsamps = ptr->execute();
}
void RESAMPLE::destroyV (void* ptr)
void RESAMPLE::Destroy(RESAMPLE* ptr)
{
delete ( (RESAMPLE*) ptr );
delete ptr;
}
} // namespace WDSP

View File

@ -87,10 +87,10 @@ public:
void setOutRate(int rate);
void setFCLow(double fc_low);
void setBandwidth(double fc_low, double fc_high);
// Exported calls
static void* createV (int in_rate, int out_rate);
static void executeV (float* input, float* output, int numsamps, int* outsamps, void* ptr);
static void destroyV (void* ptr);
// Static methods
static RESAMPLE* Create (int in_rate, int out_rate);
static void Execute (float* input, float* output, int numsamps, int* outsamps, RESAMPLE* ptr);
static void Destroy (RESAMPLE* ptr);
private:
void calc();

View File

@ -36,29 +36,20 @@ SENDER::SENDER(int _run, int _flag, int _mode, int _size, float* _in) :
flag(_flag),
mode(_mode),
size(_size),
in(_in)
in(_in),
spectrumProbe(nullptr)
{
spectrumProbe = nullptr;
}
void SENDER::flush()
{
// There is no internal data to be reset
}
void SENDER::execute()
{
if (run && flag)
{
switch (mode)
{
case 0:
{
if (spectrumProbe) {
spectrumProbe->proceed(in, size);
}
break;
}
}
if (run && flag && (mode == 0) && spectrumProbe) {
spectrumProbe->proceed(in, size);
}
}

View File

@ -50,9 +50,9 @@ SHIFT::SHIFT (
in(_in),
out(_out),
rate((double) _rate),
shift(_fshift)
shift(_fshift),
phase(0.0)
{
phase = 0.0;
calc();
}
@ -65,17 +65,19 @@ void SHIFT::execute()
{
if (run)
{
int i;
double I1, Q1, t1, t2;
double I1;
double Q1;
double t1;
double t2;
double cos_phase = cos (phase);
double sin_phase = sin (phase);
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
I1 = in[2 * i + 0];
Q1 = in[2 * i + 1];
out[2 * i + 0] = I1 * cos_phase - Q1 * sin_phase;
out[2 * i + 1] = I1 * sin_phase + Q1 * cos_phase;
out[2 * i + 0] = (float) (I1 * cos_phase - Q1 * sin_phase);
out[2 * i + 1] = (float) (I1 * sin_phase + Q1 * cos_phase);
t1 = cos_phase;
t2 = sin_phase;
cos_phase = t1 * cos_delta - t2 * sin_delta;

View File

@ -34,23 +34,25 @@ namespace WDSP {
void SIPHON::build_window()
{
int i;
double arg0, cosphi;
double sum, scale;
double arg0;
double cosphi;
double sum;
float scale;
arg0 = 2.0 * PI / ((double) fftsize - 1.0);
sum = 0.0;
for (i = 0; i < fftsize; i++)
{
cosphi = cos (arg0 * (float)i);
window[i] = + 6.3964424114390378e-02
window[i] = (float) (+ 6.3964424114390378e-02
+ cosphi * ( - 2.3993864599352804e-01
+ cosphi * ( + 3.5015956323820469e-01
+ cosphi * ( - 2.4774111897080783e-01
+ cosphi * ( + 8.5438256055858031e-02
+ cosphi * ( - 1.2320203369293225e-02
+ cosphi * ( + 4.3778825791773474e-04 ))))));
+ cosphi * ( + 4.3778825791773474e-04 )))))));
sum += window[i];
}
scale = 1.0 / sum;
scale = 1.0f / (float) sum;
for (i = 0; i < fftsize; i++)
window[i] *= scale;
}
@ -65,23 +67,23 @@ SIPHON::SIPHON(
int _sipsize,
int _fftsize,
int _specmode
)
) :
run(_run),
position(_position),
mode(_mode),
disp(_disp),
insize(_insize),
in(_in),
sipsize(_sipsize), // NOTE: sipsize MUST BE A POWER OF TWO!!
fftsize(_fftsize),
specmode(_specmode)
{
run = _run;
position = _position;
mode = _mode;
disp = _disp;
insize = _insize;
in = _in;
sipsize = _sipsize; // NOTE: sipsize MUST BE A POWER OF TWO!!
fftsize = _fftsize;
specmode = _specmode;
sipbuff.resize(sipsize * 2); // (float *) malloc0 (sipsize * sizeof (complex));
sipbuff.resize(sipsize * 2);
idx = 0;
sipout.resize(sipsize * 2); // (float *) malloc0 (sipsize * sizeof (complex));
specout.resize(fftsize * 2); // (float *) malloc0 (fftsize * sizeof (complex));
sipout.resize(sipsize * 2);
specout.resize(fftsize * 2);
sipplan = fftwf_plan_dft_1d (fftsize, (fftwf_complex *) sipout.data(), (fftwf_complex *) specout.data(), FFTW_FORWARD, FFTW_PATIENT);
window.resize(fftsize * 2); // (float *) malloc0 (fftsize * sizeof (complex));
window.resize(fftsize * 2);
build_window();
}
@ -100,35 +102,28 @@ void SIPHON::flush()
void SIPHON::execute(int pos)
{
int first, second;
int first;
int second;
if (run && position == pos)
if (run && (position == pos) && (mode == 0))
{
switch (mode)
if (insize >= sipsize)
std::copy(&(in[2 * (insize - sipsize)]), &(in[2 * (insize - sipsize)]) + sipsize * 2, sipbuff.begin());
else
{
case 0:
if (insize >= sipsize)
std::copy(&(in[2 * (insize - sipsize)]), &(in[2 * (insize - sipsize)]) + sipsize * 2, sipbuff.begin());
if (insize > (sipsize - idx))
{
first = sipsize - idx;
second = insize - first;
}
else
{
if (insize > (sipsize - idx))
{
first = sipsize - idx;
second = insize - first;
}
else
{
first = insize;
second = 0;
}
std::copy(in, in + first * 2, sipbuff.begin() + 2 * idx);
std::copy(in + 2 * first, in + 2 * first + second * 2, sipbuff.begin());
if ((idx += insize) >= sipsize) idx -= sipsize;
first = insize;
second = 0;
}
break;
case 1:
// Spectrum0 (1, disp, 0, 0, in);
break;
std::copy(in, in + first * 2, sipbuff.begin() + 2 * idx);
std::copy(in + 2 * first, in + 2 * first + second * 2, sipbuff.begin());
if ((idx += insize) >= sipsize) idx -= sipsize;
}
}
}
@ -168,8 +163,7 @@ void SIPHON::suck()
void SIPHON::sip_spectrum()
{
int i;
for (i = 0; i < fftsize; i++)
for (int i = 0; i < fftsize; i++)
{
sipout[2 * i + 0] *= window[i];
sipout[2 * i + 1] *= window[i];
@ -189,7 +183,7 @@ void SIPHON::getaSipF(float* _out, int _size)
suck ();
for (int i = 0; i < _size; i++) {
_out[i] = (float) sipout[2 * i + 0];
_out[i] = sipout[2 * i + 0];
}
}
@ -200,8 +194,8 @@ void SIPHON::getaSipF1(float* _out, int _size)
for (int i = 0; i < _size; i++)
{
_out[2 * i + 0] = (float) sipout[2 * i + 0];
_out[2 * i + 1] = (float) sipout[2 * i + 1];
_out[2 * i + 0] = sipout[2 * i + 0];
_out[2 * i + 1] = sipout[2 * i + 1];
}
}
@ -236,7 +230,11 @@ void SIPHON::setSipSpecmode(int _mode)
void SIPHON::getSpecF1(float* _out)
{ // return spectrum magnitudes in dB
int i, j, mid, m, n;
int i;
int j;
int mid;
int m;
int n;
outsize = fftsize;
suck();
sip_spectrum();
@ -262,68 +260,5 @@ void SIPHON::getSpecF1(float* _out)
}
}
/********************************************************************************************************
* *
* CALLS FOR EXTERNAL USE *
* *
********************************************************************************************************/
/*
#define MAX_EXT_SIPHONS (2) // maximum number of Siphons called from outside wdsp
__declspec (align (16)) SIPHON psiphon[MAX_EXT_SIPHONS]; // array of pointers for Siphons used EXTERNAL to wdsp
PORT
void create_siphonEXT (int id, int run, int insize, int sipsize, int fftsize, int specmode)
{
psiphon[id] = create_siphon (run, 0, 0, 0, insize, 0, sipsize, fftsize, specmode);
}
PORT
void destroy_siphonEXT (int id)
{
destroy_siphon (psiphon[id]);
}
PORT
void flush_siphonEXT (int id)
{
flush_siphon (psiphon[id]);
}
PORT
void xsiphonEXT (int id, float* buff)
{
SIPHON a = psiphon[id];
a->in = buff;
xsiphon (a, 0);
}
PORT
void GetaSipF1EXT (int id, float* out, int size)
{ // return raw samples as floats
SIPHON a = psiphon[id];
int i;
a->update.lock();
a->outsize = size;
suck (a);
a->update.unlock();
for (i = 0; i < size; i++)
{
out[2 * i + 0] = (float)a->sipout[2 * i + 0];
out[2 * i + 1] = (float)a->sipout[2 * i + 1];
}
}
PORT
void SetSiphonInsize (int id, int size)
{
SIPHON a = psiphon[id];
a->update.lock();
a->insize = size;
a->update.unlock();
}
*/
} // namespace WDSP

View File

@ -87,11 +87,6 @@ public:
void setSipDisplay(int disp);
void getSpecF1(float* out);
void setSipSpecmode(int mode);
// Calls for External Use
// static void create_siphonEXT (int id, int run, int insize, int sipsize, int fftsize, int specmode);
// static void destroy_siphonEXT (int id);
// static void xsiphonEXT (int id, float* buff);
// static void SetSiphonInsize (int id, int size);
private:
void build_window();

View File

@ -25,6 +25,8 @@ warren@wpratt.com
*/
#include <array>
#include "comm.hpp"
#include "resample.hpp"
#include "lmath.hpp"
@ -36,10 +38,75 @@ warren@wpratt.com
#include "emnr.hpp"
#include "snba.hpp"
#define MAXIMP 256
namespace WDSP {
SNBA::Exec::Exec(int xsize, int _asize, int _npasses) :
asize(_asize),
npasses(_npasses)
{
a.resize(xsize);
v.resize(xsize);
detout.resize(xsize);
savex.resize(xsize);
xHout.resize(xsize);
unfixed.resize(xsize);
}
void SNBA::Exec::fluxh()
{
std::fill (a.begin(), a.end(), 0);
std::fill (v.begin(), v.end(), 0);
std::fill (detout.begin(), detout.end(), 0);
std::fill (savex.begin(), savex.end(), 0);
std::fill (xHout.begin(), xHout.end(), 0);
std::fill (unfixed.begin(), unfixed.end(), 0);
}
SNBA::Det::Det(
int _xsize,
double _k1,
double _k2,
int _b,
int _pre,
int _post
) :
k1(_k1),
k2(_k2),
b(_b),
pre(_pre),
post(_post)
{
vp.resize(_xsize);
vpwr.resize(_xsize);
}
void SNBA::Det::flush()
{
std::fill(vp.begin(), vp.end(), 0);
std::fill(vpwr.begin(), vpwr.end(), 0);
}
SNBA::Wrk::Wrk(
int xsize,
int asize
) :
xHat_a1rows_max(xsize + asize),
xHat_a2cols_max(xsize + 2 * asize)
{
xHat_r.resize(xsize);
xHat_ATAI.resize(xsize * xsize);
xHat_A1.resize(xHat_a1rows_max * xsize);
xHat_A2.resize(xHat_a1rows_max * xHat_a2cols_max);
xHat_P1.resize(xsize * xHat_a2cols_max);
xHat_P2.resize(xsize);
trI_y.resize(xsize - 1);
trI_v.resize(xsize - 1);
dR_z.resize(xsize - 2);
asolve_r.resize(asize + 1);
asolve_z.resize(asize + 1);
}
void SNBA::calc()
{
if (inrate >= internalrate)
@ -47,8 +114,8 @@ void SNBA::calc()
else
isize = bsize * (internalrate / inrate);
inbuff = new float[isize * 2]; // (double *) malloc0 (isize * sizeof (complex));
outbuff = new float[isize * 2]; // (double *) malloc0 (isize * sizeof (complex));
inbuff = new float[isize * 2];
outbuff = new float[isize * 2];
if (inrate != internalrate)
resamprun = 1;
@ -88,7 +155,7 @@ void SNBA::calc()
iainidx = 0;
iaoutidx = 0;
inaccum = new double[iasize * 2]; // (double *) malloc0 (iasize * sizeof (double));
inaccum.resize(iasize * 2);
nsamps = 0;
if (incr > isize)
@ -105,7 +172,7 @@ void SNBA::calc()
}
init_oaoutidx = oaoutidx;
outaccum = new double[oasize * 2]; // (double *) malloc0 (oasize * sizeof (double));
outaccum.resize(oasize * 2);
}
SNBA::SNBA(
@ -140,15 +207,12 @@ SNBA::SNBA(
iasize(0),
iainidx(0),
iaoutidx(0),
inaccum(nullptr),
xbase(nullptr),
xaux(nullptr),
nsamps(0),
oasize(0),
oainidx(0),
oaoutidx(0),
init_oaoutidx(0),
outaccum(nullptr),
resamprun(0),
isize(0),
inresamp(nullptr),
@ -156,80 +220,29 @@ SNBA::SNBA(
inbuff(nullptr),
outbuff(nullptr),
out_low_cut(_out_low_cut),
out_high_cut(_out_high_cut)
out_high_cut(_out_high_cut),
exec(_xsize, _asize, _npasses),
sdet(_xsize, _k1, _k2, _b, _pre, _post),
wrk(_xsize, _asize)
{
exec.asize = _asize;
exec.npasses = _npasses;
sdet.k1 = _k1;
sdet.k2 = _k2;
sdet.b = _b;
sdet.pre = _pre;
sdet.post = _post;
scan.pmultmin = _pmultmin;
calc();
xbase = new double[2 * xsize]; // (double *) malloc0 (2 * xsize * sizeof (double));
xaux = xbase + xsize;
exec.a = new double[xsize]; //(double *) malloc0 (xsize * sizeof (double));
exec.v = new double[xsize]; //(double *) malloc0 (xsize * sizeof (double));
exec.detout = new int[xsize]; //(int *) malloc0 (xsize * sizeof (int));
exec.savex = new double[xsize]; //(double *) malloc0 (xsize * sizeof (double));
exec.xHout = new double[xsize]; //(double *) malloc0 (xsize * sizeof (double));
exec.unfixed = new int[xsize]; //(int *) malloc0 (xsize * sizeof (int));
sdet.vp = new double[xsize]; //(double *) malloc0 (xsize * sizeof (double));
sdet.vpwr = new double[xsize]; //(double *) malloc0 (xsize * sizeof (double));
wrk.xHat_a1rows_max = xsize + exec.asize;
wrk.xHat_a2cols_max = xsize + 2 * exec.asize;
wrk.xHat_r = new double[xsize]; // (double *) malloc0 (xsize * sizeof(double));
wrk.xHat_ATAI = new double[xsize * xsize]; // (double *) malloc0 (xsize * xsize * sizeof(double));
wrk.xHat_A1 = new double[wrk.xHat_a1rows_max * xsize]; // (double *) malloc0 (wrk.xHat_a1rows_max * xsize * sizeof(double));
wrk.xHat_A2 = new double[wrk.xHat_a1rows_max * wrk.xHat_a2cols_max]; // (double *) malloc0 (wrk.xHat_a1rows_max * wrk.xHat_a2cols_max * sizeof(double));
wrk.xHat_P1 = new double[xsize * wrk.xHat_a2cols_max]; // (double *) malloc0 (xsize * wrk.xHat_a2cols_max * sizeof(double));
wrk.xHat_P2 = new double[xsize]; // (double *) malloc0 (xsize * sizeof(double));
wrk.trI_y = new double[xsize - 1]; // (double *) malloc0 ((xsize - 1) * sizeof(double));
wrk.trI_v = new double[xsize - 1]; // (double *) malloc0 ((xsize - 1) * sizeof(double));
wrk.dR_z = new double[xsize - 2]; // (double *) malloc0 ((xsize - 2) * sizeof(double));
wrk.asolve_r = new double[exec.asize + 1]; // (double *) malloc0 ((exec.asize + 1) * sizeof(double));
wrk.asolve_z = new double[exec.asize + 1]; // (double *) malloc0 ((exec.asize + 1) * sizeof(double));
xbase.resize(2 * xsize);
xaux = &xbase[xsize];
}
void SNBA::decalc()
{
delete (outresamp);
delete (inresamp);
delete[] (outbuff);
delete[] (inbuff);
delete[] (outaccum);
delete[] (inaccum);
delete outresamp;
delete inresamp;
delete[] outbuff;
delete[] inbuff;
}
SNBA::~SNBA()
{
delete[] (wrk.xHat_r);
delete[] (wrk.xHat_ATAI);
delete[] (wrk.xHat_A1);
delete[] (wrk.xHat_A2);
delete[] (wrk.xHat_P1);
delete[] (wrk.xHat_P2);
delete[] (wrk.trI_y);
delete[] (wrk.trI_v);
delete[] (wrk.dR_z);
delete[] (wrk.asolve_r);
delete[] (wrk.asolve_z);
delete[] (sdet.vpwr);
delete[] (sdet.vp);
delete[] (exec.unfixed);
delete[] (exec.xHout);
delete[] (exec.savex);
delete[] (exec.detout);
delete[] (exec.v);
delete[] (exec.a);
delete[] (xbase);
decalc();
}
@ -241,20 +254,13 @@ void SNBA::flush()
oainidx = 0;
oaoutidx = init_oaoutidx;
memset (inaccum, 0, iasize * sizeof (double));
memset (outaccum, 0, oasize * sizeof (double));
memset (xaux, 0, xsize * sizeof (double));
memset (exec.a, 0, xsize * sizeof (double));
memset (exec.v, 0, xsize * sizeof (double));
memset (exec.detout, 0, xsize * sizeof (int));
memset (exec.savex, 0, xsize * sizeof (double));
memset (exec.xHout, 0, xsize * sizeof (double));
memset (exec.unfixed, 0, xsize * sizeof (int));
memset (sdet.vp, 0, xsize * sizeof (double));
memset (sdet.vpwr, 0, xsize * sizeof (double));
std::fill(inbuff, inbuff + isize * 2, 0);
std::fill(outbuff, outbuff + isize * 2, 0);
exec.fluxh();
sdet.flush();
std::fill(inaccum.begin(), inaccum.end(), 0);
std::fill(outaccum.begin(), outaccum.end(), 0);
std::fill(xaux, xaux + xsize, 0);
std::fill(inbuff, inbuff + isize * 2, 0);
std::fill(outbuff, outbuff + isize * 2, 0);
inresamp->flush();
outresamp->flush();
@ -282,27 +288,26 @@ void SNBA::setSize(int size)
calc();
}
void SNBA::ATAc0 (int n, int nr, double* A, double* r)
void SNBA::ATAc0 (int n, int nr, std::vector<double>& A, std::vector<double>& r)
{
int i, j;
memset(r, 0, n * sizeof (double));
std::fill(r.begin(), r.begin() + n, 0);
for (i = 0; i < n; i++)
for (int i = 0; i < n; i++)
{
for (j = 0; j < nr; j++)
for (int j = 0; j < nr; j++)
r[i] += A[j * n + i] * A[j * n + 0];
}
}
void SNBA::multA1TA2(double* a1, double* a2, int m, int n, int q, double* c)
void SNBA::multA1TA2(std::vector<double>& a1, std::vector<double>& a2, int m, int n, int q, std::vector<double>& c)
{
int i, j, k;
int k;
int p = q - m;
memset (c, 0, m * n * sizeof (double));
std::fill(c.begin(), c.begin() + m*n, 0);
for (i = 0; i < m; i++)
for (int i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
for (int j = 0; j < n; j++)
{
if (j < p)
{
@ -318,12 +323,12 @@ void SNBA::multA1TA2(double* a1, double* a2, int m, int n, int q, double* c)
}
}
void SNBA::multXKE(double* a, double* xk, int m, int q, int p, double* vout)
void SNBA::multXKE(std::vector<double>& a, const double* xk, int m, int q, int p, std::vector<double>& vout)
{
int i, k;
memset (vout, 0, m * sizeof (double));
int k;
std::fill(vout.begin(), vout.begin() + m, 0);
for (i = 0; i < m; i++)
for (int i = 0; i < m; i++)
{
for (k = i; k < p; k++)
vout[i] += a[i * q + k] * xk[k];
@ -332,14 +337,13 @@ void SNBA::multXKE(double* a, double* xk, int m, int q, int p, double* vout)
}
}
void SNBA::multAv(double* a, double* v, int m, int q, double* vout)
void SNBA::multAv(std::vector<double>& a, std::vector<double>& v, int m, int q, std::vector<double>& vout)
{
int i, k;
memset (vout, 0, m * sizeof (double));
std::fill(vout.begin(), vout.begin() + m, 0);
for (i = 0; i < m; i++)
for (int i = 0; i < m; i++)
{
for (k = 0; k < q; k++)
for (int k = 0; k < q; k++)
vout[i] += a[i * q + k] * v[k];
}
}
@ -347,29 +351,31 @@ void SNBA::multAv(double* a, double* v, int m, int q, double* vout)
void SNBA::xHat(
int xusize,
int asize,
double* xk,
double* a,
double* xout,
double* r,
double* ATAI,
double* A1,
double* A2,
double* P1,
double* P2,
double* trI_y,
double* trI_v,
double* dR_z
const double* xk,
std::vector<double>& a,
std::vector<double>& xout,
std::vector<double>& r,
std::vector<double>& ATAI,
std::vector<double>& A1,
std::vector<double>& A2,
std::vector<double>& P1,
std::vector<double>& P2,
std::vector<double>& trI_y,
std::vector<double>& trI_v,
std::vector<double>& dR_z
)
{
int i, j, k;
int i;
int j;
int k;
int a1rows = xusize + asize;
int a2cols = xusize + 2 * asize;
memset (r, 0, xusize * sizeof(double)); // work space
memset (ATAI, 0, xusize * xusize * sizeof(double)); // work space
memset (A1, 0, a1rows * xusize * sizeof(double)); // work space
memset (A2, 0, a1rows * a2cols * sizeof(double)); // work space
memset (P1, 0, xusize * a2cols * sizeof(double)); // work space
memset (P2, 0, xusize * sizeof(double)); // work space
std::fill (r.begin(), r.begin() + xusize, 0); // work space
std::fill (ATAI.begin(), ATAI.begin() + xusize * xusize, 0); // work space
std::fill (A1.begin(), A1.begin() + a1rows * xusize, 0); // work space
std::fill (A2.begin(), A2.begin() + a1rows * a2cols, 0); // work space
std::fill (P1.begin(), P1.begin() + xusize * a2cols, 0); // work space
std::fill (P2.begin(), P2.begin() + xusize, 0); // work space
for (i = 0; i < xusize; i++)
{
@ -380,28 +386,29 @@ void SNBA::xHat(
}
for (i = 0; i < asize; i++)
{
for (k = asize - i - 1, j = 0; k < asize; k++, j++)
A2[j * a2cols + i] = a[k];
}
{
for (k = asize - i - 1, j = 0; k < asize; k++, j++)
A2[j * a2cols + i] = a[k];
}
for (i = asize + xusize; i < 2 * asize + xusize; i++)
{
A2[(i - asize) * a2cols + i] = - 1.0;
for (j = i - asize + 1, k = 0; j < xusize + asize; j++, k++)
A2[j * a2cols + i] = a[k];
}
{
A2[(i - asize) * a2cols + i] = - 1.0;
for (j = i - asize + 1, k = 0; j < xusize + asize; j++, k++)
A2[j * a2cols + i] = a[k];
}
ATAc0(xusize, xusize + asize, A1, r);
LMathd::trI(xusize, r, ATAI, trI_y, trI_v, dR_z);
LMathd::trI(xusize, r.data(), ATAI.data(), trI_y.data(), trI_v.data(), dR_z.data());
multA1TA2(A1, A2, xusize, 2 * asize + xusize, xusize + asize, P1);
multXKE(P1, xk, xusize, xusize + 2 * asize, asize, P2);
multAv(ATAI, P2, xusize, xusize, xout);
}
void SNBA::invf(int xsize, int asize, double* a, double* x, double* v)
void SNBA::invf(int xsize, int asize, std::vector<double>& a, const double* x, std::vector<double>& v)
{
int i, j;
memset (v, 0, xsize * sizeof (double));
int i;
int j;
std::fill(v.begin(), v.begin() + xsize, 0);
for (i = asize; i < xsize - asize; i++)
{
@ -417,12 +424,16 @@ void SNBA::invf(int xsize, int asize, double* a, double* x, double* v)
}
}
void SNBA::det(int asize, double* v, int* detout)
void SNBA::det(int asize, std::vector<double>& v, std::vector<int>& detout)
{
int i, j;
int i;
int j;
double medpwr;
double t1, t2;
int bstate, bcount, bsamp;
double t1;
double t2;
int bstate;
int bcount;
int bsamp;
for (i = asize, j = 0; i < xsize; i++, j++)
{
@ -430,7 +441,7 @@ void SNBA::det(int asize, double* v, int* detout)
sdet.vp[j] = sdet.vpwr[i];
}
LMathd::median(xsize - asize, sdet.vp, &medpwr);
LMathd::median(xsize - asize, sdet.vp.data(), &medpwr);
t1 = sdet.k1 * medpwr;
t2 = 0.0;
@ -492,6 +503,8 @@ void SNBA::det(int asize, double* v, int* detout)
bstate = 1;
}
break;
default:
break;
}
}
@ -525,24 +538,26 @@ int SNBA::scanFrame(
int xsize,
int pval,
double pmultmin,
int* det,
int* bimp,
int* limp,
int* befimp,
int* aftimp,
int* p_opt,
std::vector<int>& det,
std::array<int, MAXIMP>& bimp,
std::array<int, MAXIMP>& limp,
std::array<int, MAXIMP>& befimp,
std::array<int, MAXIMP>& aftimp,
std::array<int, MAXIMP>& p_opt,
int* next
)
{
int inflag = 0;
int i = 0, j = 0, k = 0;
int i = 0;
int j = 0;
int k = 0;
int nimp = 0;
double td;
int ti;
double merit[MAXIMP] = { 0 };
int nextlist[MAXIMP];
memset (befimp, 0, MAXIMP * sizeof (int));
memset (aftimp, 0, MAXIMP * sizeof (int));
std::array<double, MAXIMP> merit = { 0 };
std::array<int, MAXIMP> nextlist;
std::fill(befimp.begin(), befimp.end(), 0);
std::fill(aftimp.begin(), aftimp.end(), 0);
while (i < xsize && nimp < MAXIMP)
{
@ -555,7 +570,8 @@ int SNBA::scanFrame(
}
else if (det[i] == 1)
{
limp[nimp - 1]++;
if (nimp > 0)
limp[nimp - 1]++;
}
else
{
@ -634,22 +650,20 @@ int SNBA::scanFrame(
void SNBA::execFrame(double* x)
{
int i, k;
int pass;
int nimp;
int bimp[MAXIMP];
int limp[MAXIMP];
int befimp[MAXIMP];
int aftimp[MAXIMP];
int p_opt[MAXIMP];
std::array<int, MAXIMP> bimp;
std::array<int, MAXIMP> limp;
std::array<int, MAXIMP> befimp;
std::array<int, MAXIMP> aftimp;
std::array<int, MAXIMP> p_opt;
int next = 0;
int p;
memcpy (exec.savex, x, xsize * sizeof (double));
LMathd::asolve(xsize, exec.asize, x, exec.a, wrk.asolve_r, wrk.asolve_z);
std::copy(x, x + xsize, exec.savex.begin());
LMathd::asolve(xsize, exec.asize, x, exec.a.data(), wrk.asolve_r.data(), wrk.asolve_z.data());
invf(xsize, exec.asize, exec.a, x, exec.v);
det(exec.asize, exec.v, exec.detout);
for (i = 0; i < xsize; i++)
for (int i = 0; i < xsize; i++)
{
if (exec.detout[i] != 0)
x[i] = 0.0;
@ -657,18 +671,18 @@ void SNBA::execFrame(double* x)
nimp = scanFrame(xsize, exec.asize, scan.pmultmin, exec.detout, bimp, limp, befimp, aftimp, p_opt, &next);
for (pass = 0; pass < exec.npasses; pass++)
for (int pass = 0; pass < exec.npasses; pass++)
{
memcpy (exec.unfixed, exec.detout, xsize * sizeof (int));
std::copy(exec.detout.begin(), exec.detout.end(), exec.unfixed.begin());
for (k = 0; k < nimp; k++)
for (int k = 0; k < nimp; k++)
{
if (k > 0)
scanFrame(xsize, exec.asize, scan.pmultmin, exec.unfixed, bimp, limp, befimp, aftimp, p_opt, &next);
if ((p = p_opt[next]) > 0)
{
LMathd::asolve(xsize, p, x, exec.a, wrk.asolve_r, wrk.asolve_z);
LMathd::asolve(xsize, p, x, exec.a.data(), wrk.asolve_r.data(), wrk.asolve_z.data());
xHat(
limp[next],
p,
@ -685,7 +699,7 @@ void SNBA::execFrame(double* x)
wrk.trI_v,
wrk.dR_z
);
memcpy (&x[bimp[next]], exec.xHout, limp[next] * sizeof (double));
std::copy(exec.xHout.begin(), exec.xHout.begin() + limp[next], &x[bimp[next]]);
memset (&exec.unfixed[bimp[next]], 0, limp[next] * sizeof (int));
}
else
@ -719,12 +733,12 @@ void SNBA::execute()
nsamps -= incr;
memcpy (&outaccum[oainidx], xaux, incr * sizeof (double));
oainidx = (oainidx + incr) % oasize;
memmove (xbase, &xbase[incr], (2 * xsize - incr) * sizeof (double));
std::copy(&xbase[incr], &xbase[incr] + (2 * xsize - incr), xbase.begin());
}
for (i = 0; i < isize; i++)
{
outbuff[2 * i + 0] = outaccum[oaoutidx];
outbuff[2 * i + 0] = (float) outaccum[oaoutidx];
outbuff[2 * i + 1] = 0.0;
oaoutidx = (oaoutidx + 1) % oasize;
}
@ -792,7 +806,8 @@ void SNBA::setPmultmin(double pmultmin)
void SNBA::setOutputBandwidth(double flow, double fhigh)
{
double f_low, f_high;
double f_low = 0;
double f_high = 0;
if (flow >= 0 && fhigh >= 0)
{
@ -802,7 +817,7 @@ void SNBA::setOutputBandwidth(double flow, double fhigh)
if (flow > out_high_cut)
flow = out_high_cut;
f_low = std::max ( out_low_cut, flow);
f_low = std::max (out_low_cut, flow);
f_high = std::min (out_high_cut, fhigh);
}
else if (flow <= 0 && fhigh <= 0)
@ -813,7 +828,7 @@ void SNBA::setOutputBandwidth(double flow, double fhigh)
if (fhigh < -out_high_cut)
fhigh = -out_high_cut;
f_low = std::max ( out_low_cut, -fhigh);
f_low = std::max (out_low_cut, -fhigh);
f_high = std::min (out_high_cut, -flow);
}
else if (flow < 0 && fhigh > 0)

View File

@ -28,11 +28,15 @@ warren@wpratt.com
#ifndef wdsp_snba_h
#define wdsp_snba_h
#include <vector>
#include "export.h"
namespace WDSP{
class RESAMPLE;
class SNBA
class WDSP_API SNBA
{
public:
int run;
@ -47,15 +51,15 @@ public:
int iasize;
int iainidx;
int iaoutidx;
double* inaccum;
double* xbase;
std::vector<double> inaccum;
std::vector<double> xbase;
double* xaux;
int nsamps;
int oasize;
int oainidx;
int oaoutidx;
int init_oaoutidx;
double* outaccum;
std::vector<double> outaccum;
int resamprun;
int isize;
RESAMPLE *inresamp;
@ -64,48 +68,72 @@ public:
float* outbuff;
double out_low_cut;
double out_high_cut;
static const int MAXIMP = 256;
struct _exec
struct Exec
{
int asize;
double* a;
double* v;
int* detout;
double* savex;
double* xHout;
int* unfixed;
std::vector<double> a;
std::vector<double> v;
std::vector<int> detout;
std::vector<double> savex;
std::vector<double> xHout;
std::vector<int> unfixed;
int npasses;
} exec;
struct _det
Exec(int xsize, int _asize, int _npasses);
void fluxh();
};
Exec exec;
struct Det
{
double k1;
double k2;
int b;
int pre;
int post;
double* vp;
double* vpwr;
} sdet;
struct _scan
std::vector<double> vp;
std::vector<double> vpwr;
Det(
int xsize,
double k1,
double k2,
int b,
int pre,
int post
);
void flush();
};
Det sdet;
struct Scan
{
double pmultmin;
} scan;
struct _wrk
};
Scan scan;
struct Wrk
{
int xHat_a1rows_max;
int xHat_a2cols_max;
double* xHat_r;
double* xHat_ATAI;
double* xHat_A1;
double* xHat_A2;
double* xHat_P1;
double* xHat_P2;
double* trI_y;
double* trI_v;
double* dR_z;
double* asolve_r;
double* asolve_z;
} wrk;
std::vector<double> xHat_r;
std::vector<double> xHat_ATAI;
std::vector<double> xHat_A1;
std::vector<double> xHat_A2;
std::vector<double> xHat_P1;
std::vector<double> xHat_P2;
std::vector<double> trI_y;
std::vector<double> trI_v;
std::vector<double> dR_z;
std::vector<double> asolve_r;
std::vector<double> asolve_z;
Wrk(
int xsize,
int asize
);
void flush();
};
Wrk wrk;
SNBA(
int run,
@ -149,40 +177,40 @@ public:
private:
void calc();
void decalc();
static void ATAc0 (int n, int nr, double* A, double* r);
static void multA1TA2(double* a1, double* a2, int m, int n, int q, double* c);
static void multXKE(double* a, double* xk, int m, int q, int p, double* vout);
static void multAv(double* a, double* v, int m, int q, double* vout);
static void ATAc0 (int n, int nr, std::vector<double>& A, std::vector<double>& r);
static void multA1TA2(std::vector<double>& a1, std::vector<double>& a2, int m, int n, int q, std::vector<double>& c);
static void multXKE(std::vector<double>& a, const double* xk, int m, int q, int p, std::vector<double>& vout);
static void multAv(std::vector<double>& a, std::vector<double>& v, int m, int q, std::vector<double>& vout);
static void xHat(
int xusize,
int asize,
double* xk,
double* a,
double* xout,
double* r,
double* ATAI,
double* A1,
double* A2,
double* P1,
double* P2,
double* trI_y,
double* trI_v,
double* dR_z
const double* xk,
std::vector<double>& a,
std::vector<double>& xout,
std::vector<double>& r,
std::vector<double>& ATAI,
std::vector<double>& A1,
std::vector<double>& A2,
std::vector<double>& P1,
std::vector<double>& P2,
std::vector<double>& trI_y,
std::vector<double>& trI_v,
std::vector<double>& dR_z
);
static void invf(int xsize, int asize, double* a, double* x, double* v);
static void invf(int xsize, int asize, std::vector<double>& a, const double* x, std::vector<double>& v);
static int scanFrame(
int xsize,
int pval,
double pmultmin,
int* det,
int* bimp,
int* limp,
int* befimp,
int* aftimp,
int* p_opt,
std::vector<int>& det,
std::array<int, MAXIMP>& bimp,
std::array<int, MAXIMP>& limp,
std::array<int, MAXIMP>& befimp,
std::array<int, MAXIMP>& aftimp,
std::array<int, MAXIMP>& p_opt,
int* next
);
void det(int asize, double* v, int* detout);
void det(int asize, std::vector<double>& v, std::vector<int>& detout);
void execFrame(double* x);
};

View File

@ -38,8 +38,11 @@ namespace WDSP {
void SNOTCH::calc()
{
double fn, qk, qr, csn;
fn = f / (double) rate;
double fn;
double qk;
double qr;
double csn;
fn = f / rate;
csn = cos (TWOPI * fn);
qr = 1.0 - 3.0 * bw;
qk = (1.0 - 2.0 * qr * csn + qr * qr) / (2.0 * (1.0 - csn));
@ -80,11 +83,10 @@ void SNOTCH::execute()
{
if (run)
{
int i;
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
x0 = in[2 * i + 0];
out[2 * i + 0] = a0 * x0 + a1 * x1 + a2 * x2 + b1 * y1 + b2 * y2;
out[2 * i + 0] = (float) (a0 * x0 + a1 * x1 + a2 * x2 + b1 * y1 + b2 * y2);
y2 = y1;
y1 = out[2 * i + 0];
x2 = x1;

View File

@ -48,8 +48,16 @@ public:
double rate;
double f;
double bw;
double a0, a1, a2, b1, b2;
double x0, x1, x2, y1, y2;
double a0;
double a1;
double a2;
double b1;
double b2;
double x0;
double x1;
double x2;
double y1;
double y2;
SNOTCH(
int run,
@ -62,7 +70,7 @@ public:
);
SNOTCH(const SNOTCH&) = delete;
SNOTCH& operator=(SNOTCH& other) = delete;
~SNOTCH() {}
~SNOTCH() = default;
void flush();
void execute();

View File

@ -39,31 +39,38 @@ namespace WDSP {
void SPEAK::calc()
{
double ratio;
double f_corr, g_corr, bw_corr, bw_parm, A, f_min;
double f_corr;
double g_corr;
double bw_corr;
double bw_parm;
double A;
double f_min;
switch (design)
{
case 0:
ratio = bw / f;
switch (nstages)
if (nstages == 4)
{
case 4:
bw_parm = 2.4;
f_corr = 1.0 - 0.160 * ratio + 1.440 * ratio * ratio;
g_corr = 1.0 - 1.003 * ratio + 3.990 * ratio * ratio;
break;
default:
}
else
{
bw_parm = 1.0;
f_corr = 1.0;
g_corr = 1.0;
break;
}
{
double fn, qk, qr, csn;
double fn;
double qk;
double qr;
double csn;
fgain = gain / g_corr;
fn = f / (double)rate / f_corr;
fn = f / rate / f_corr;
csn = cos (TWOPI * fn);
qr = 1.0 - 3.0 * bw / (double)rate * bw_parm;
qr = 1.0 - 3.0 * bw / rate * bw_parm;
qk = (1.0 - 2.0 * qr * csn + qr * qr) / (2.0 * (1.0 - csn));
a0 = 1.0 - qk;
a1 = 2.0 * (qk - qr) * csn;
@ -76,26 +83,27 @@ void SPEAK::calc()
case 1:
if (f < 200.0) f = 200.0;
ratio = bw / f;
switch (nstages)
if (nstages == 4)
{
case 4:
bw_parm = 5.0;
bw_corr = 1.13 * ratio - 0.956 * ratio * ratio;
A = 2.5;
f_min = 50.0;
break;
default:
}
else
{
bw_parm = 1.0;
bw_corr = 1.0;
g_corr = 1.0;
A = 2.5;
f_min = 50.0;
break;
}
{
double w0, sn, c, den;
double w0;
double sn;
double c;
double den;
if (f < f_min) f = f_min;
w0 = TWOPI * f / (double)rate;
w0 = TWOPI * f / rate;
sn = sin (w0);
cbw = bw_corr * f;
c = sn * sinh(0.5 * log((f + 0.5 * cbw * bw_parm) / (f - 0.5 * cbw * bw_parm)) * w0 / sn);
@ -108,6 +116,8 @@ void SPEAK::calc()
fgain = gain / pow (A * A, (double)nstages);
}
break;
default:
break;
}
flush();
}
@ -135,12 +145,12 @@ SPEAK::SPEAK(
nstages(_nstages),
design(_design)
{
x0.resize(nstages * 2); // (float *) malloc0 (nstages * sizeof (complex));
x1.resize(nstages * 2); // (float *) malloc0 (nstages * sizeof (complex));
x2.resize(nstages * 2); //(float *) malloc0 (nstages * sizeof (complex));
y0.resize(nstages * 2); // (float *) malloc0 (nstages * sizeof (complex));
y1.resize(nstages * 2); // (float *) malloc0 (nstages * sizeof (complex));
y2.resize(nstages * 2); // (float *) malloc0 (nstages * sizeof (complex));
x0.resize(nstages * 2);
x1.resize(nstages * 2);
x2.resize(nstages * 2);
y0.resize(nstages * 2);
y1.resize(nstages * 2);
y2.resize(nstages * 2);
calc();
}
@ -178,7 +188,7 @@ void SPEAK::execute()
x1[2 * n + j] = x0[2 * n + j];
}
out[2 * i + j] = y0[2 * (nstages - 1) + j];
out[2 * i + j] = (float) y0[2 * (nstages - 1) + j];
}
}
}

View File

@ -55,8 +55,17 @@ public:
double fgain;
int nstages;
int design;
double a0, a1, a2, b1, b2;
std::vector<double> x0, x1, x2, y0, y1, y2;
double a0;
double a1;
double a2;
double b1;
double b2;
std::vector<double> x0;
std::vector<double> x1;
std::vector<double> x2;
std::vector<double> y0;
std::vector<double> y1;
std::vector<double> y2;
SPEAK(
int run,
@ -72,7 +81,7 @@ public:
);
SPEAK(const SPEAK&) = delete;
SPEAK& operator=(const SPEAK& other) = delete;
~SPEAK() {}
~SPEAK() = default;
void flush();
void execute();

View File

@ -81,14 +81,13 @@ void SPHP::execute()
{
if (run)
{
int i, j, n;
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
for (j = 0; j < 2; j++)
for (int j = 0; j < 2; j++)
{
x0[j] = in[2 * i + j];
for (n = 0; n < nstages; n++)
for (int n = 0; n < nstages; n++)
{
if (n > 0)
x0[2 * n + j] = y0[2 * (n - 1) + j];
@ -100,7 +99,7 @@ void SPHP::execute()
x1[2 * n + j] = x0[2 * n + j];
}
out[2 * i + j] = y0[2 * (nstages - 1) + j];
out[2 * i + j] = (float) y0[2 * (nstages - 1) + j];
}
}
}

View File

@ -56,7 +56,7 @@ FTOV::FTOV(
in = _in;
out = _out;
eps = 0.01;
ring.resize(rsize); // (int*) malloc0 (rsize * sizeof (int));
ring.resize(rsize);
rptr = 0;
inlast = 0.0;
rcount = 0;
@ -91,7 +91,7 @@ void FTOV::execute()
rcount++; // increment the count
}
if (++rptr == rsize) rptr = 0; // increment and wrap the pointer as needed
out[0] = std::min (1.0, (double)rcount / div); // calculate the output sample
out[0] = (float) std::min (1.0, (double)rcount / div); // calculate the output sample
inlast = in[size - 1]; // save the last input sample for next buffer
for (int i = 1; i < size; i++)
{
@ -107,7 +107,7 @@ void FTOV::execute()
rcount++; // increment the count
}
if (++rptr == rsize) rptr = 0; // increment and wrap the pointer as needed
out[i] = std::min(1.0, (double)rcount / div); // calculate the output sample
out[i] = (float) std::min(1.0, (double)rcount / div); // calculate the output sample
}
}
}
@ -118,7 +118,8 @@ void FTOV::execute()
void SSQL::compute_slews()
{
double delta, theta;
double delta;
double theta;
delta = PI / (double) ntup;
theta = 0.0;
for (int i = 0; i <= ntup; i++)
@ -137,15 +138,33 @@ void SSQL::compute_slews()
void SSQL::calc()
{
b1 = new float[size * 2]; // (float*) malloc0 (size * sizeof (complex));
dcbl = new CBL(1, size, in, b1, 0, rate, 0.02);
ibuff = new float[size]; // (float*) malloc0 (size * sizeof (float));
ftovbuff = new float[size]; // (float*) malloc0(size * sizeof (float));
cvtr = new FTOV(1, size, rate, ftov_rsize, ftov_fmax, ibuff, ftovbuff);
lpbuff = new float[size]; // (float*) malloc0 (size * sizeof (float));
filt = new DBQLP(1, size, ftovbuff, lpbuff, rate, 11.3, 1.0, 1.0, 1);
wdbuff = new int[size]; // (int*) malloc0 (size * sizeof (int));
tr_signal = new int[size]; // (int*) malloc0 (size * sizeof (int));
b1.resize(size * 2);
dcbl = new CBL(1, size, in, b1.data(), 0, rate, 0.02);
ibuff.resize(size);
ftovbuff.resize(size);
cvtr = new FTOV(
1,
size,
rate,
ftov_rsize,
ftov_fmax,
ibuff.data(),
ftovbuff.data()
);
lpbuff.resize(size);
filt = new DBQLP(
1,
size,
ftovbuff.data(),
lpbuff.data(),
rate,
11.3,
1.0,
1.0,
1
);
wdbuff.resize(size);
tr_signal.resize(size);
// window detector
wdmult = exp (-1.0 / (rate * wdtau));
wdaverage = 0.0;
@ -156,27 +175,19 @@ void SSQL::calc()
// level change
ntup = (int)(tup * rate);
ntdown = (int)(tdown * rate);
cup = new float[ntup + 1]; // (float*) malloc0 ((ntup + 1) * sizeof (float));
cdown = new float[ntdown + 1]; // (float*) malloc0 ((ntdown + 1) * sizeof (float));
cup.resize(ntup + 1);
cdown.resize(ntdown + 1);
compute_slews();
// control
state = 0;
state = SSQLState::MUTED;
count = 0;
}
void SSQL::decalc()
{
delete[] (tr_signal);
delete[] (wdbuff);
delete (filt);
delete[] (lpbuff);
delete (cvtr);
delete[] (ftovbuff);
delete[] (ibuff);
delete (dcbl);
delete[] (b1);
delete[] (cdown);
delete[] (cup);
delete filt;
delete cvtr;
delete dcbl;
}
SSQL::SSQL(
@ -223,24 +234,17 @@ SSQL::~SSQL()
void SSQL::flush()
{
std::fill(b1, b1 + size * 2, 0);
std::fill(b1.begin(), b1.end(), 0);
dcbl->flush();
memset (ibuff, 0, size * sizeof (float));
memset (ftovbuff, 0, size * sizeof (float));
std::fill(ibuff.begin(), ibuff.end(), 0);
std::fill(ftovbuff.begin(), ftovbuff.end(), 0);
cvtr->flush();
memset (lpbuff, 0, size * sizeof (float));
std::fill(lpbuff.begin(), lpbuff.end(), 0);
filt->flush();
memset (wdbuff, 0, size * sizeof (int));
memset (tr_signal, 0, size * sizeof (int));
std::fill(wdbuff.begin(), wdbuff.end(), 0);
std::fill(tr_signal.begin(), tr_signal.end(), 0);
}
enum _ssqlstate
{
MUTED,
INCREASE,
UNMUTED,
DECREASE
};
void SSQL::execute()
{
@ -277,35 +281,35 @@ void SSQL::execute()
{
switch (state)
{
case MUTED:
case SSQLState::MUTED:
if (tr_signal[i] == 1)
{
state = INCREASE;
state = SSQLState::INCREASE;
count = ntup;
}
out[2 * i + 0] = muted_gain * in[2 * i + 0];
out[2 * i + 1] = muted_gain * in[2 * i + 1];
out[2 * i + 0] = (float) (muted_gain * in[2 * i + 0]);
out[2 * i + 1] = (float) (muted_gain * in[2 * i + 1]);
break;
case INCREASE:
out[2 * i + 0] = in[2 * i + 0] * cup[ntup - count];
out[2 * i + 1] = in[2 * i + 1] * cup[ntup - count];
case SSQLState::INCREASE:
out[2 * i + 0] = (float) (in[2 * i + 0] * cup[ntup - count]);
out[2 * i + 1] = (float) (in[2 * i + 1] * cup[ntup - count]);
if (count-- == 0)
state = UNMUTED;
state = SSQLState::UNMUTED;
break;
case UNMUTED:
case SSQLState::UNMUTED:
if (tr_signal[i] == 0)
{
state = DECREASE;
state = SSQLState::DECREASE;
count = ntdown;
}
out[2 * i + 0] = in[2 * i + 0];
out[2 * i + 1] = in[2 * i + 1];
break;
case DECREASE:
out[2 * i + 0] = in[2 * i + 0] * cdown[ntdown - count];
out[2 * i + 1] = in[2 * i + 1] * cdown[ntdown - count];
case SSQLState::DECREASE:
out[2 * i + 0] = (float) (in[2 * i + 0] * cdown[ntdown - count]);
out[2 * i + 1] = (float) (in[2 * i + 1] * cdown[ntdown - count]);
if (count-- == 0)
state = MUTED;
state = SSQLState::MUTED;
break;
}
}

View File

@ -75,26 +75,33 @@ class DBQLP;
class WDSP_API SSQL // Syllabic Squelch
{
public:
enum class SSQLState
{
MUTED,
INCREASE,
UNMUTED,
DECREASE
};
int run; // 0 if squelch system is OFF; 1 if it's ON
int size; // size of input/output buffers
float* in; // squelch input signal buffer
float* out; // squelch output signal buffer
int rate; // sample rate
int state; // state machine control
SSQLState state; // state machine control
int count; // count variable for raised cosine transitions
double tup; // time for turn-on transition
double tdown; // time for turn-off transition
int ntup; // number of samples for turn-on transition
int ntdown; // number of samples for turn-off transition
float* cup; // coefficients for up-slew
float* cdown; // coefficients for down-slew
std::vector<double> cup; // coefficients for up-slew
std::vector<double> cdown; // coefficients for down-slew
double muted_gain; // audio gain while muted; 0.0 for complete silence
float* b1; // buffer to hold output of dc-block function
float* ibuff; // buffer containing only 'I' component
float* ftovbuff; // buffer containing output of f to v converter
float* lpbuff; // buffer containing output of low-pass filter
int* wdbuff; // buffer containing output of window detector
std::vector<float> b1; // buffer to hold output of dc-block function
std::vector<float> ibuff; // buffer containing only 'I' component
std::vector<float> ftovbuff; // buffer containing output of f to v converter
std::vector<float> lpbuff; // buffer containing output of low-pass filter
std::vector<int> wdbuff; // buffer containing output of window detector
CBL *dcbl; // pointer to DC Blocker data structure
FTOV *cvtr; // pointer to F to V Converter data structure
DBQLP *filt; // pointer to Bi-Quad Low-Pass Filter data structure
@ -114,7 +121,7 @@ public:
double tr_voltage; // trigger voltage
double mute_mult; // multiplier for successive voltage calcs when muted
double unmute_mult; // multiplier for successive voltage calcs when unmuted
int* tr_signal; // trigger signal, 0 or 1
std::vector<int> tr_signal; // trigger signal, 0 or 1
SSQL(
int run,

View File

@ -146,7 +146,8 @@ void WCPAGC::flush()
void WCPAGC::execute()
{
int i, j, k;
int i;
int k;
double mult;
if (run)
@ -155,8 +156,8 @@ void WCPAGC::execute()
{
for (i = 0; i < io_buffsize; i++)
{
out[2 * i + 0] = fixed_gain * in[2 * i + 0];
out[2 * i + 1] = fixed_gain * in[2 * i + 1];
out[2 * i + 0] = (float) (fixed_gain * in[2 * i + 0]);
out[2 * i + 1] = (float) (fixed_gain * in[2 * i + 1]);
}
return;
@ -173,8 +174,10 @@ void WCPAGC::execute()
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];
ring[2 * in_index + 0] = in[2 * i + 0];
ring[2 * in_index + 1] = in[2 * i + 1];
double xr = ring[2 * in_index + 0];
double xi = ring[2 * in_index + 1];
if (pmode == 0)
abs_ring[in_index] = std::max(fabs(xr), fabs(xi));
@ -189,7 +192,7 @@ void WCPAGC::execute()
ring_max = 0.0;
k = out_index;
for (j = 0; j < attack_buffsize; j++)
for (int j = 0; j < attack_buffsize; j++)
{
if (++k == ring_buffsize)
k = 0;
@ -323,6 +326,8 @@ void WCPAGC::execute()
}
break;
}
default:
break;
}
if (volts < min_volts)
@ -330,8 +335,8 @@ void WCPAGC::execute()
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;
out[2 * i + 0] = (float) (out_sample[0] * mult);
out[2 * i + 1] = (float) (out_sample[1] * mult);
}
}
else if (out != in)
@ -406,7 +411,7 @@ void WCPAGC::setMode(int _mode)
void WCPAGC::setFixed(double _fixed_agc)
{
fixed_gain = pow (10.0, (double) _fixed_agc / 20.0);
fixed_gain = pow (10.0, _fixed_agc / 20.0);
loadWcpAGC();
}
@ -428,7 +433,7 @@ void WCPAGC::setHang(int _hang)
loadWcpAGC();
}
void WCPAGC::getHangLevel(double *hangLevel)
void WCPAGC::getHangLevel(double *hangLevel) const
//for line on bandscope
{
*hangLevel = 20.0 * log10(hang_level / 0.637);
@ -437,7 +442,8 @@ void WCPAGC::getHangLevel(double *hangLevel)
void WCPAGC::setHangLevel(double _hangLevel)
//for line on bandscope
{
double convert, tmp;
double convert;
double tmp;
if (max_input > min_volts)
{
@ -451,7 +457,7 @@ void WCPAGC::setHangLevel(double _hangLevel)
loadWcpAGC();
}
void WCPAGC::getHangThreshold(int *hangthreshold)
void WCPAGC::getHangThreshold(int *hangthreshold) const
//for slider in setup
{
*hangthreshold = (int) (100.0 * hang_thresh);
@ -464,7 +470,7 @@ void WCPAGC::setHangThreshold(int _hangthreshold)
loadWcpAGC();
}
void WCPAGC::getTop(double *max_agc)
void WCPAGC::getTop(double *max_agc) const
//for AGC Max Gain in setup
{
*max_agc = 20 * log10 (max_gain);
@ -473,7 +479,7 @@ void WCPAGC::getTop(double *max_agc)
void WCPAGC::setTop(double _max_agc)
//for AGC Max Gain in setup
{
max_gain = pow (10.0, (double) _max_agc / 20.0);
max_gain = pow (10.0, _max_agc / 20.0);
loadWcpAGC();
}
@ -489,9 +495,9 @@ void WCPAGC::setMaxInputLevel(double _level)
loadWcpAGC();
}
void WCPAGC::setRun(int state)
void WCPAGC::setRun(int _state)
{
run = state;
run = _state;
}
} // namespace WDSP

View File

@ -145,11 +145,11 @@ public:
void setAttack(int attack);
void setDecay(int decay);
void setHang(int hang);
void getHangLevel(double *hangLevel);
void getHangLevel(double *hangLevel) const;
void setHangLevel(double hangLevel);
void getHangThreshold(int *hangthreshold);
void getHangThreshold(int *hangthreshold) const;
void setHangThreshold(int hangthreshold);
void getTop(double *max_agc);
void getTop(double *max_agc) const;
void setTop(double max_agc);
void setSlope(int slope);
void setMaxInputLevel(double level);