mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 09:18:54 -05:00
834 lines
20 KiB
C++
834 lines
20 KiB
C++
/* snb.c
|
|
|
|
This file is part of a program that implements a Software-Defined Radio.
|
|
|
|
Copyright (C) 2015, 2016 Warren Pratt, NR0V
|
|
Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
The author can be reached by email at
|
|
|
|
warren@wpratt.com
|
|
|
|
*/
|
|
|
|
#include "comm.hpp"
|
|
#include "resample.hpp"
|
|
#include "lmath.hpp"
|
|
#include "firmin.hpp"
|
|
#include "nbp.hpp"
|
|
#include "amd.hpp"
|
|
#include "anf.hpp"
|
|
#include "anr.hpp"
|
|
#include "emnr.hpp"
|
|
#include "snba.hpp"
|
|
|
|
#define MAXIMP 256
|
|
|
|
namespace WDSP {
|
|
|
|
void SNBA::calc()
|
|
{
|
|
if (inrate >= internalrate)
|
|
isize = bsize / (inrate / internalrate);
|
|
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));
|
|
|
|
if (inrate != internalrate)
|
|
resamprun = 1;
|
|
else
|
|
resamprun = 0;
|
|
|
|
inresamp = new RESAMPLE(
|
|
resamprun,
|
|
bsize,
|
|
in,
|
|
inbuff,
|
|
inrate,
|
|
internalrate,
|
|
0.0,
|
|
0,
|
|
2.0
|
|
);
|
|
inresamp->setFCLow(250.0);
|
|
outresamp = new RESAMPLE(
|
|
resamprun,
|
|
isize,
|
|
outbuff,
|
|
out,
|
|
internalrate,
|
|
inrate,
|
|
0.0,
|
|
0,
|
|
2.0
|
|
);
|
|
outresamp->setFCLow(200.0);
|
|
incr = xsize / ovrlp;
|
|
|
|
if (incr > isize)
|
|
iasize = incr;
|
|
else
|
|
iasize = isize;
|
|
|
|
iainidx = 0;
|
|
iaoutidx = 0;
|
|
inaccum = new double[iasize * 2]; // (double *) malloc0 (iasize * sizeof (double));
|
|
nsamps = 0;
|
|
|
|
if (incr > isize)
|
|
{
|
|
oasize = incr;
|
|
oainidx = 0;
|
|
oaoutidx = isize;
|
|
}
|
|
else
|
|
{
|
|
oasize = isize;
|
|
oainidx = 0;
|
|
oaoutidx = 0;
|
|
}
|
|
|
|
init_oaoutidx = oaoutidx;
|
|
outaccum = new double[oasize * 2]; // (double *) malloc0 (oasize * sizeof (double));
|
|
}
|
|
|
|
SNBA::SNBA(
|
|
int _run,
|
|
float* _in,
|
|
float* _out,
|
|
int _inrate,
|
|
int _internalrate,
|
|
int _bsize,
|
|
int _ovrlp,
|
|
int _xsize,
|
|
int _asize,
|
|
int _npasses,
|
|
double _k1,
|
|
double _k2,
|
|
int _b,
|
|
int _pre,
|
|
int _post,
|
|
double _pmultmin,
|
|
double _out_low_cut,
|
|
double _out_high_cut
|
|
) :
|
|
run(_run),
|
|
in(_in),
|
|
out(_out),
|
|
inrate(_inrate),
|
|
internalrate(_internalrate),
|
|
bsize(_bsize),
|
|
xsize(_xsize),
|
|
ovrlp(_ovrlp),
|
|
incr(0),
|
|
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),
|
|
outresamp(nullptr),
|
|
inbuff(nullptr),
|
|
outbuff(nullptr),
|
|
out_low_cut(_out_low_cut),
|
|
out_high_cut(_out_high_cut)
|
|
{
|
|
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));
|
|
}
|
|
|
|
void SNBA::decalc()
|
|
{
|
|
delete (outresamp);
|
|
delete (inresamp);
|
|
delete[] (outbuff);
|
|
delete[] (inbuff);
|
|
delete[] (outaccum);
|
|
delete[] (inaccum);
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
void SNBA::flush()
|
|
{
|
|
iainidx = 0;
|
|
iaoutidx = 0;
|
|
nsamps = 0;
|
|
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);
|
|
|
|
inresamp->flush();
|
|
outresamp->flush();
|
|
}
|
|
|
|
void SNBA::setBuffers(float* _in, float* _out)
|
|
{
|
|
decalc();
|
|
in = _in;
|
|
out = _out;
|
|
calc();
|
|
}
|
|
|
|
void SNBA::setSamplerate(int rate)
|
|
{
|
|
decalc();
|
|
inrate = rate;
|
|
calc();
|
|
}
|
|
|
|
void SNBA::setSize(int size)
|
|
{
|
|
decalc();
|
|
bsize = size;
|
|
calc();
|
|
}
|
|
|
|
void SNBA::ATAc0 (int n, int nr, double* A, double* r)
|
|
{
|
|
int i, j;
|
|
memset(r, 0, n * sizeof (double));
|
|
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
for (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)
|
|
{
|
|
int i, j, k;
|
|
int p = q - m;
|
|
memset (c, 0, m * n * sizeof (double));
|
|
|
|
for (i = 0; i < m; i++)
|
|
{
|
|
for (j = 0; j < n; j++)
|
|
{
|
|
if (j < p)
|
|
{
|
|
for (k = i; k <= std::min(i + p, j); k++)
|
|
c[i * n + j] += a1[k * m + i] * a2[k * n + j];
|
|
}
|
|
if (j >= n - p)
|
|
{
|
|
for (k = std::max(i, q - (n - j)); k <= i + p; k++)
|
|
c[i * n + j] += a1[k * m + i] * a2[k * n + j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SNBA::multXKE(double* a, double* xk, int m, int q, int p, double* vout)
|
|
{
|
|
int i, k;
|
|
memset (vout, 0, m * sizeof (double));
|
|
|
|
for (i = 0; i < m; i++)
|
|
{
|
|
for (k = i; k < p; k++)
|
|
vout[i] += a[i * q + k] * xk[k];
|
|
for (k = q - p; k <= q - m + i; k++)
|
|
vout[i] += a[i * q + k] * xk[k];
|
|
}
|
|
}
|
|
|
|
void SNBA::multAv(double* a, double* v, int m, int q, double* vout)
|
|
{
|
|
int i, k;
|
|
memset (vout, 0, m * sizeof (double));
|
|
|
|
for (i = 0; i < m; i++)
|
|
{
|
|
for (k = 0; k < q; k++)
|
|
vout[i] += a[i * q + k] * v[k];
|
|
}
|
|
}
|
|
|
|
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
|
|
)
|
|
{
|
|
int i, j, 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
|
|
|
|
for (i = 0; i < xusize; i++)
|
|
{
|
|
A1[i * xusize + i] = 1.0;
|
|
k = i + 1;
|
|
for (j = k; j < k + asize; j++)
|
|
A1[j * xusize + i] = - a[j - k];
|
|
}
|
|
|
|
for (i = 0; i < asize; i++)
|
|
{
|
|
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];
|
|
}
|
|
|
|
ATAc0(xusize, xusize + asize, A1, r);
|
|
LMathd::trI(xusize, r, ATAI, trI_y, trI_v, dR_z);
|
|
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)
|
|
{
|
|
int i, j;
|
|
memset (v, 0, xsize * sizeof (double));
|
|
|
|
for (i = asize; i < xsize - asize; i++)
|
|
{
|
|
for (j = 0; j < asize; j++)
|
|
v[i] += a[j] * (x[i - 1 - j] + x[i + 1 + j]);
|
|
v[i] = x[i] - 0.5 * v[i];
|
|
}
|
|
for (i = xsize - asize; i < xsize; i++)
|
|
{
|
|
for (j = 0; j < asize; j++)
|
|
v[i] += a[j] * x[i - 1 - j];
|
|
v[i] = x[i] - v[i];
|
|
}
|
|
}
|
|
|
|
void SNBA::det(int asize, double* v, int* detout)
|
|
{
|
|
int i, j;
|
|
double medpwr;
|
|
double t1, t2;
|
|
int bstate, bcount, bsamp;
|
|
|
|
for (i = asize, j = 0; i < xsize; i++, j++)
|
|
{
|
|
sdet.vpwr[i] = v[i] * v[i];
|
|
sdet.vp[j] = sdet.vpwr[i];
|
|
}
|
|
|
|
LMathd::median(xsize - asize, sdet.vp, &medpwr);
|
|
t1 = sdet.k1 * medpwr;
|
|
t2 = 0.0;
|
|
|
|
for (i = asize; i < xsize; i++)
|
|
{
|
|
if (sdet.vpwr[i] <= t1)
|
|
t2 += sdet.vpwr[i];
|
|
else if (sdet.vpwr[i] <= 2.0 * t1)
|
|
t2 += 2.0 * t1 - sdet.vpwr[i];
|
|
}
|
|
t2 *= sdet.k2 / (double) (xsize - asize);
|
|
|
|
for (i = asize; i < xsize; i++)
|
|
{
|
|
if (sdet.vpwr[i] > t2)
|
|
detout[i] = 1;
|
|
else
|
|
detout[i] = 0;
|
|
}
|
|
|
|
bstate = 0;
|
|
bcount = 0;
|
|
bsamp = 0;
|
|
|
|
for (i = asize; i < xsize; i++)
|
|
{
|
|
switch (bstate)
|
|
{
|
|
case 0:
|
|
if (detout[i] == 1)
|
|
bstate = 1;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
if (detout[i] == 0)
|
|
{
|
|
bstate = 2;
|
|
bsamp = i;
|
|
bcount = 1;
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
++bcount;
|
|
|
|
if (bcount > sdet.b)
|
|
{
|
|
if (detout[i] == 1)
|
|
bstate = 1;
|
|
else
|
|
bstate = 0;
|
|
}
|
|
else if (detout[i] == 1)
|
|
{
|
|
for (j = bsamp; j < bsamp + bcount - 1; j++)
|
|
detout[j] = 1;
|
|
bstate = 1;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (i = asize; i < xsize; i++)
|
|
{
|
|
if (detout[i] == 1)
|
|
{
|
|
for (j = i - 1; j > i - 1 - sdet.pre; j--)
|
|
{
|
|
if (j >= asize)
|
|
detout[j] = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = xsize - 1; i >= asize; i--)
|
|
{
|
|
if (detout[i] == 1)
|
|
{
|
|
for (j = i + 1; j < i + 1 + sdet.post; j++)
|
|
{
|
|
if (j < xsize)
|
|
detout[j] = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int SNBA::scanFrame(
|
|
int xsize,
|
|
int pval,
|
|
double pmultmin,
|
|
int* det,
|
|
int* bimp,
|
|
int* limp,
|
|
int* befimp,
|
|
int* aftimp,
|
|
int* p_opt,
|
|
int* next
|
|
)
|
|
{
|
|
int inflag = 0;
|
|
int i = 0, j = 0, 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));
|
|
|
|
while (i < xsize && nimp < MAXIMP)
|
|
{
|
|
if (det[i] == 1 && inflag == 0)
|
|
{
|
|
inflag = 1;
|
|
bimp[nimp] = i;
|
|
limp[nimp] = 1;
|
|
nimp++;
|
|
}
|
|
else if (det[i] == 1)
|
|
{
|
|
limp[nimp - 1]++;
|
|
}
|
|
else
|
|
{
|
|
inflag = 0;
|
|
befimp[nimp]++;
|
|
if (nimp > 0)
|
|
aftimp[nimp - 1]++;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
for (i = 0; i < nimp; i++)
|
|
{
|
|
if (befimp[i] < aftimp[i])
|
|
p_opt[i] = befimp[i];
|
|
else
|
|
p_opt[i] = aftimp[i];
|
|
|
|
if (p_opt[i] > pval)
|
|
p_opt[i] = pval;
|
|
|
|
if (p_opt[i] < (int)(pmultmin * limp[i]))
|
|
p_opt[i] = -1;
|
|
}
|
|
|
|
for (i = 0; i < nimp; i++)
|
|
{
|
|
merit[i] = (double)p_opt[i] / (double)limp[i];
|
|
nextlist[i] = i;
|
|
}
|
|
|
|
for (j = 0; j < nimp - 1; j++)
|
|
{
|
|
for (k = 0; k < nimp - j - 1; k++)
|
|
{
|
|
if (merit[k] < merit[k + 1])
|
|
{
|
|
td = merit[k];
|
|
ti = nextlist[k];
|
|
merit[k] = merit[k + 1];
|
|
nextlist[k] = nextlist[k + 1];
|
|
merit[k + 1] = td;
|
|
nextlist[k + 1] = ti;
|
|
}
|
|
}
|
|
}
|
|
|
|
i = 1;
|
|
|
|
if (nimp > 0)
|
|
{
|
|
while (merit[i] == merit[0] && i < nimp)
|
|
i++;
|
|
}
|
|
|
|
for (j = 0; j < i - 1; j++)
|
|
{
|
|
for (k = 0; k < i - j - 1; k++)
|
|
{
|
|
if (limp[nextlist[k]] < limp[nextlist[k + 1]])
|
|
{
|
|
td = merit[k];
|
|
ti = nextlist[k];
|
|
merit[k] = merit[k + 1];
|
|
nextlist[k] = nextlist[k + 1];
|
|
merit[k + 1] = td;
|
|
nextlist[k + 1] = ti;
|
|
}
|
|
}
|
|
}
|
|
|
|
*next = nextlist[0];
|
|
return nimp;
|
|
}
|
|
|
|
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];
|
|
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);
|
|
invf(xsize, exec.asize, exec.a, x, exec.v);
|
|
det(exec.asize, exec.v, exec.detout);
|
|
|
|
for (i = 0; i < xsize; i++)
|
|
{
|
|
if (exec.detout[i] != 0)
|
|
x[i] = 0.0;
|
|
}
|
|
|
|
nimp = scanFrame(xsize, exec.asize, scan.pmultmin, exec.detout, bimp, limp, befimp, aftimp, p_opt, &next);
|
|
|
|
for (pass = 0; pass < exec.npasses; pass++)
|
|
{
|
|
memcpy (exec.unfixed, exec.detout, xsize * sizeof (int));
|
|
|
|
for (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);
|
|
xHat(
|
|
limp[next],
|
|
p,
|
|
&x[bimp[next] - p],
|
|
exec.a,
|
|
exec.xHout,
|
|
wrk.xHat_r,
|
|
wrk.xHat_ATAI,
|
|
wrk.xHat_A1,
|
|
wrk.xHat_A2,
|
|
wrk.xHat_P1,
|
|
wrk.xHat_P2,
|
|
wrk.trI_y,
|
|
wrk.trI_v,
|
|
wrk.dR_z
|
|
);
|
|
memcpy (&x[bimp[next]], exec.xHout, limp[next] * sizeof (double));
|
|
memset (&exec.unfixed[bimp[next]], 0, limp[next] * sizeof (int));
|
|
}
|
|
else
|
|
{
|
|
memcpy (&x[bimp[next]], &exec.savex[bimp[next]], limp[next] * sizeof (double));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SNBA::execute()
|
|
{
|
|
if (run)
|
|
{
|
|
int i;
|
|
inresamp->execute();
|
|
|
|
for (i = 0; i < 2 * isize; i += 2)
|
|
{
|
|
inaccum[iainidx] = inbuff[i];
|
|
iainidx = (iainidx + 1) % iasize;
|
|
}
|
|
|
|
nsamps += isize;
|
|
|
|
while (nsamps >= incr)
|
|
{
|
|
memcpy (&xaux[xsize - incr], &inaccum[iaoutidx], incr * sizeof (double));
|
|
execFrame (xaux);
|
|
iaoutidx = (iaoutidx + incr) % iasize;
|
|
nsamps -= incr;
|
|
memcpy (&outaccum[oainidx], xaux, incr * sizeof (double));
|
|
oainidx = (oainidx + incr) % oasize;
|
|
memmove (xbase, &xbase[incr], (2 * xsize - incr) * sizeof (double));
|
|
}
|
|
|
|
for (i = 0; i < isize; i++)
|
|
{
|
|
outbuff[2 * i + 0] = outaccum[oaoutidx];
|
|
outbuff[2 * i + 1] = 0.0;
|
|
oaoutidx = (oaoutidx + 1) % oasize;
|
|
}
|
|
|
|
outresamp->execute();
|
|
}
|
|
else if (out != in)
|
|
{
|
|
std::copy(in, in + bsize * 2, out);
|
|
}
|
|
}
|
|
|
|
/********************************************************************************************************
|
|
* *
|
|
* Public Properties *
|
|
* *
|
|
********************************************************************************************************/
|
|
|
|
void SNBA::setOvrlp(int _ovrlp)
|
|
{
|
|
decalc();
|
|
ovrlp = _ovrlp;
|
|
calc();
|
|
}
|
|
|
|
void SNBA::setAsize(int size)
|
|
{
|
|
exec.asize = size;
|
|
}
|
|
|
|
void SNBA::setNpasses(int npasses)
|
|
{
|
|
exec.npasses = npasses;
|
|
}
|
|
|
|
void SNBA::setK1(double k1)
|
|
{
|
|
sdet.k1 = k1;
|
|
}
|
|
|
|
void SNBA::setK2(double k2)
|
|
{
|
|
sdet.k2 = k2;
|
|
}
|
|
|
|
void SNBA::setBridge(int bridge)
|
|
{
|
|
sdet.b = bridge;
|
|
}
|
|
|
|
void SNBA::setPresamps(int presamps)
|
|
{
|
|
sdet.pre = presamps;
|
|
}
|
|
|
|
void SNBA::setPostsamps(int postsamps)
|
|
{
|
|
sdet.post = postsamps;
|
|
}
|
|
|
|
void SNBA::setPmultmin(double pmultmin)
|
|
{
|
|
scan.pmultmin = pmultmin;
|
|
}
|
|
|
|
void SNBA::setOutputBandwidth(double flow, double fhigh)
|
|
{
|
|
double f_low, f_high;
|
|
|
|
if (flow >= 0 && fhigh >= 0)
|
|
{
|
|
if (fhigh < out_low_cut)
|
|
fhigh = out_low_cut;
|
|
|
|
if (flow > out_high_cut)
|
|
flow = out_high_cut;
|
|
|
|
f_low = std::max ( out_low_cut, flow);
|
|
f_high = std::min (out_high_cut, fhigh);
|
|
}
|
|
else if (flow <= 0 && fhigh <= 0)
|
|
{
|
|
if (flow > -out_low_cut)
|
|
flow = -out_low_cut;
|
|
|
|
if (fhigh < -out_high_cut)
|
|
fhigh = -out_high_cut;
|
|
|
|
f_low = std::max ( out_low_cut, -fhigh);
|
|
f_high = std::min (out_high_cut, -flow);
|
|
}
|
|
else if (flow < 0 && fhigh > 0)
|
|
{
|
|
double absmax = std::max (-flow, fhigh);
|
|
|
|
if (absmax < out_low_cut)
|
|
absmax = out_low_cut;
|
|
|
|
f_low = out_low_cut;
|
|
f_high = std::min (out_high_cut, absmax);
|
|
}
|
|
|
|
outresamp->setBandwidth(f_low, f_high);
|
|
}
|
|
|
|
} // namespace
|