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:
parent
841e980c7c
commit
2f22ef6012
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user