1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-05-28 21:12:26 -04:00

DATV demod: fixed some memory management issues in cfft_engine

This commit is contained in:
f4exb 2021-03-19 07:23:53 +01:00
parent 841e980c7c
commit 2f22ef6012
3 changed files with 80 additions and 45 deletions

View File

@ -61,9 +61,27 @@ struct cconverter : runnable
template <typename T>
struct cfft_engine
{
const int n;
cfft_engine(int _n) : n(_n), invsqrtn(1.0 / sqrt(n))
cfft_engine(int _n) :
bitrev(nullptr),
omega(nullptr),
omega_rev(nullptr)
{
init(_n);
}
~cfft_engine() {
release();
}
int size() {
return n;
}
void init(int _n)
{
release();
n = _n;
invsqrtn = 1.0 / sqrt(n);
// Compute log2(n)
logn = 0;
for (int t = n; t > 1; t >>= 1)
@ -86,6 +104,7 @@ struct cfft_engine
omega_rev[i].im = -(omega[i].im = sinf(a));
}
}
void inplace(complex<T> *data, bool reverse = false)
{
// Bit-reversal permutation
@ -133,10 +152,25 @@ struct cfft_engine
}
private:
int logn;
void release()
{
if (bitrev) {
delete[] bitrev;
}
if (omega) {
delete[] omega;
}
if (omega_rev) {
delete[] omega_rev;
}
}
int *bitrev;
complex<T> *omega, *omega_rev;
complex<T> *omega;
complex<T> *omega_rev;
int n;
float invsqrtn;
int logn;
};
template <typename T>

View File

@ -604,7 +604,7 @@ struct s2_frame_receiver : runnable
fprintf(stderr, "COARSE(%d): %f rad/symb (%.0f Hz at %.0f baud)\n",
coarse_count, freqw, freqw * Fm / (2 * M_PI), Fm);
#if 0
freqw16 = freqw * 65536 / (2*M_PI);
freqw16 = freqw * 65536 / (2*M_PI);
#else
fprintf(stderr, "Ignoring coarse det, using %f\n", freqw16 * Fm / 65536);
#endif

View File

@ -62,7 +62,7 @@ struct auto_notch : runnable
k(0.002), // k(0.01)
fft(4096),
in(_in),
out(_out, fft.n),
out(_out, fft.size()),
nslots(_nslots),
phase(0),
gain(1),
@ -73,7 +73,7 @@ struct auto_notch : runnable
for (int s = 0; s < nslots; ++s)
{
__slots[s].i = -1;
__slots[s].expj = new complex<float>[fft.n];
__slots[s].expj = new complex<float>[fft.size()];
}
}
@ -88,9 +88,9 @@ struct auto_notch : runnable
void run()
{
while (in.readable() >= fft.n && out.writable() >= fft.n)
while (in.readable() >= fft.size() && out.writable() >= fft.size())
{
phase += fft.n;
phase += fft.size();
if (phase >= decimation)
{
@ -99,18 +99,18 @@ struct auto_notch : runnable
}
process();
in.read(fft.n);
out.written(fft.n);
in.read(fft.size());
out.written(fft.size());
}
}
void detect()
{
complex<T> *pin = in.rd();
complex<float> *data = new complex<float>[fft.n];
complex<float> *data = new complex<float>[fft.size()];
float m0 = 0, m2 = 0;
for (int i = 0; i < fft.n; ++i)
for (int i = 0; i < fft.size(); ++i)
{
data[i].re = pin[i].re;
data[i].im = pin[i].im;
@ -123,7 +123,7 @@ struct auto_notch : runnable
if (agc_rms_setpoint && m2)
{
float rms = gen_sqrt(m2 / fft.n);
float rms = gen_sqrt(m2 / fft.size());
if (sch->debug)
fprintf(stderr, "(pow %f max %f)", rms, m0);
float new_gain = agc_rms_setpoint / rms;
@ -131,16 +131,16 @@ struct auto_notch : runnable
}
fft.inplace(data, true);
float *amp = new float[fft.n];
float *amp = new float[fft.size()];
for (int i = 0; i < fft.n; ++i)
for (int i = 0; i < fft.size(); ++i)
amp[i] = hypotf(data[i].re, data[i].im);
for (slot *s = __slots; s < __slots + nslots; ++s)
{
int iamax = 0;
for (int i = 0; i < fft.n; ++i)
for (int i = 0; i < fft.size(); ++i)
if (amp[i] > amp[iamax])
iamax = i;
@ -154,9 +154,9 @@ struct auto_notch : runnable
s->estim.im = 0;
s->estt = 0;
for (int i = 0; i < fft.n; ++i)
for (int i = 0; i < fft.size(); ++i)
{
float a = 2 * M_PI * s->i * i / fft.n;
float a = 2 * M_PI * s->i * i / fft.size();
s->expj[i].re = cosf(a);
s->expj[i].im = sinf(a);
}
@ -167,7 +167,7 @@ struct auto_notch : runnable
if (iamax - 1 >= 0)
amp[iamax - 1] = 0;
if (iamax + 1 < fft.n)
if (iamax + 1 < fft.size())
amp[iamax + 1] = 0;
}
@ -177,7 +177,7 @@ struct auto_notch : runnable
void process()
{
complex<T> *pin = in.rd(), *pend = pin + fft.n, *pout = out.wr();
complex<T> *pin = in.rd(), *pend = pin + fft.size(), *pout = out.wr();
for (slot *s = __slots; s < __slots + nslots; ++s)
s->ej = s->expj;
@ -1809,7 +1809,7 @@ struct cnr_fft : runnable
kavg(0.1),
in(_in),
out(_out),
fft(nfft),
fft(nfft < 128 ? 128 : nfft > 4096 ? 4096 : nfft),
avgpower(nullptr),
sorted(nullptr),
data(nullptr),
@ -1819,7 +1819,8 @@ struct cnr_fft : runnable
nslots_shift_ratio(0.65),
nslots_ratio(0.1)
{
fprintf(stderr, "cnr_fft::cnr_fft: bw: %f FFT: %d\n", bandwidth, fft.n);
fprintf(stderr, "cnr_fft::cnr_fft: bw: %f FFT: %d\n", bandwidth, fft.size());
if (bandwidth > 0.25) {
fail("cnr_fft::cnr_fft: CNR estimator requires Fsampling > 4x Fsignal");
}
@ -1843,9 +1844,9 @@ struct cnr_fft : runnable
void run()
{
while (in.readable() >= fft.n && out.writable() >= 1)
while (in.readable() >= fft.size() && out.writable() >= 1)
{
phase += fft.n;
phase += fft.size();
if (phase >= decimation)
{
@ -1853,7 +1854,7 @@ struct cnr_fft : runnable
do_cnr();
}
in.read(fft.n);
in.read(fft.size());
}
}
@ -1866,38 +1867,38 @@ struct cnr_fft : runnable
void do_cnr()
{
if (!sorted) {
sorted = new T[fft.n];
sorted = new T[fft.size()];
}
if (!data) {
data = new complex<T>[fft.n];
data = new complex<T>[fft.size()];
}
if (!power) {
power = new T[fft.n];
power = new T[fft.size()];
}
float center_freq = freq_tap ? *freq_tap * tap_multiplier : 0;
int icf = floor(center_freq * fft.n + 0.5);
memcpy(data, in.rd(), fft.n * sizeof(data[0]));
int icf = floor(center_freq * fft.size() + 0.5);
memcpy(data, in.rd(), fft.size() * sizeof(data[0]));
fft.inplace(data, true);
for (int i = 0; i < fft.n; ++i)
for (int i = 0; i < fft.size(); ++i)
power[i] = data[i].re * data[i].re + data[i].im * data[i].im;
if (!avgpower)
{
// Initialize with first spectrum
avgpower = new T[fft.n];
memcpy(avgpower, power, fft.n * sizeof(avgpower[0]));
avgpower = new T[fft.size()];
memcpy(avgpower, power, fft.size() * sizeof(avgpower[0]));
}
// Accumulate and low-pass filter (exponential averaging)
for (int i = 0; i < fft.n; ++i) {
for (int i = 0; i < fft.size(); ++i) {
avgpower[i] = avgpower[i] * (1 - kavg) + power[i] * kavg;
}
#define LEANDVB_SDR_CNR_METHOD 2
#if LEANDVB_SDR_CNR_METHOD == 0
int bwslots = (bandwidth / 4) * fft.n;
int bwslots = (bandwidth / 4) * fft.size();
if (!bwslots) {
return;
@ -1909,9 +1910,9 @@ struct cnr_fft : runnable
float n2 = ( avgslots(icf-bwslots*4, icf-bwslots*3) +
avgslots(icf+bwslots*3, icf+bwslots*4) ) / 2;
#elif LEANDVB_SDR_CNR_METHOD == 1
int cbwslots = bandwidth * cslots_ratio * fft.n;
int nstart = bandwidth * nslots_shift_ratio * fft.n;
int nstop = nstart + bandwidth * nslots_ratio * fft.n;
int cbwslots = bandwidth * cslots_ratio * fft.size();
int nstart = bandwidth * nslots_shift_ratio * fft.size();
int nstop = nstart + bandwidth * nslots_ratio * fft.size();
if (!cbwslots || !nstart || !nstop) {
return;
@ -1923,7 +1924,7 @@ struct cnr_fft : runnable
float n2 = (avgslots(icf - nstop, icf - nstart) +
avgslots(icf + nstart, icf + nstop)) / 2;
#elif LEANDVB_SDR_CNR_METHOD == 2
int bw = bandwidth * 0.75 * fft.n;
int bw = bandwidth * 0.75 * fft.size();
float c2plusn2 = 0;
float n2 = 0;
minmax(icf - bw, icf + bw, n2, c2plusn2);
@ -1939,8 +1940,8 @@ struct cnr_fft : runnable
for (int i = i0; i <= i1; ++i)
{
int j = i < 0 ? fft.n + i : i;
s += avgpower[j < 0 ? 0 : j >= fft.n ? fft.n-1 : j];
int j = i < 0 ? fft.size() + i : i;
s += avgpower[j < 0 ? 0 : j >= fft.size() ? fft.size()-1 : j];
}
return s / (i1 - i0 + 1);
@ -1950,10 +1951,10 @@ struct cnr_fft : runnable
{
int l = 0;
for (int i = i0; i <= i1; ++i, ++l)
for (int i = i0; i <= i1 && l < fft.size(); ++i, ++l)
{
int j = i < 0 ? fft.n + i : i;
sorted[l] = avgpower[j < 0 ? 0 : j >= fft.n ? fft.n-1 : j];
int j = i < 0 ? fft.size() + i : i;
sorted[l] = avgpower[j < 0 ? 0 : j >= fft.size() ? fft.size()-1 : j];
}
std::sort(sorted, &sorted[l]);