DATV: CNR optimization

This commit is contained in:
f4exb 2021-03-14 10:54:37 +01:00
parent 4ff5d7d76d
commit 227245eb94
2 changed files with 26 additions and 13 deletions

View File

@ -668,7 +668,7 @@ void DATVDemodSink::InitDATVFramework()
if (m_objCfg.cnr == true) if (m_objCfg.cnr == true)
{ {
r_cnr = new leansdr::cnr_fft<leansdr::f32>(m_objScheduler, *p_preprocessed, *p_cnr, m_objCfg.Fm/m_objCfg.Fs); r_cnr = new leansdr::cnr_fft<leansdr::f32>(m_objScheduler, *p_preprocessed, *p_cnr, m_objCfg.Fm/m_objCfg.Fs, 1024);
r_cnr->decimation = decimation(m_objCfg.Fs, 5); // 5 Hz r_cnr->decimation = decimation(m_objCfg.Fs, 5); // 5 Hz
} }
@ -1000,7 +1000,7 @@ void DATVDemodSink::InitDATVS2Framework()
if (m_objCfg.cnr == true) if (m_objCfg.cnr == true)
{ {
r_cnr = new leansdr::cnr_fft<leansdr::f32>(m_objScheduler, *p_preprocessed, *p_cnr, m_objCfg.Fm/m_objCfg.Fs); r_cnr = new leansdr::cnr_fft<leansdr::f32>(m_objScheduler, *p_preprocessed, *p_cnr, m_objCfg.Fm/m_objCfg.Fs, 1024);
r_cnr->decimation = decimation(m_objCfg.Fs, 5); // 5 Hz r_cnr->decimation = decimation(m_objCfg.Fs, 5); // 5 Hz
} }

View File

@ -1796,7 +1796,8 @@ struct cnr_fft : runnable
scheduler *sch, scheduler *sch,
pipebuf<complex<T>> &_in, pipebuf<complex<T>> &_in,
pipebuf<float> &_out, pipebuf<float> &_out,
float _bandwidth, int nfft = 4096 float _bandwidth,
int nfft = 4096
) : ) :
runnable(sch, "cnr_fft"), runnable(sch, "cnr_fft"),
bandwidth(_bandwidth), bandwidth(_bandwidth),
@ -1808,6 +1809,8 @@ struct cnr_fft : runnable
out(_out), out(_out),
fft(nfft), fft(nfft),
avgpower(nullptr), avgpower(nullptr),
data(nullptr),
power(nullptr),
phase(0), phase(0),
cslots_ratio(0.2), cslots_ratio(0.2),
nslots_shift_ratio(0.65), nslots_shift_ratio(0.65),
@ -1824,6 +1827,12 @@ struct cnr_fft : runnable
if (avgpower) { if (avgpower) {
delete[] avgpower; delete[] avgpower;
} }
if (data) {
delete[] data;
}
if (power) {
delete[] power;
}
} }
void run() void run()
@ -1850,12 +1859,17 @@ struct cnr_fft : runnable
private: private:
void do_cnr() void do_cnr()
{ {
if (!data) {
data = new complex<T>[fft.n];
}
if (!power) {
power = new T[fft.n];
}
float center_freq = freq_tap ? *freq_tap * tap_multiplier : 0; float center_freq = freq_tap ? *freq_tap * tap_multiplier : 0;
int icf = floor(center_freq * fft.n + 0.5); int icf = floor(center_freq * fft.n + 0.5);
complex<T> *data = new complex<T>[fft.n];
memcpy(data, in.rd(), fft.n * sizeof(data[0])); memcpy(data, in.rd(), fft.n * sizeof(data[0]));
fft.inplace(data, true); fft.inplace(data, true);
T *power = new T[fft.n];
for (int i = 0; i < fft.n; ++i) for (int i = 0; i < fft.n; ++i)
power[i] = data[i].re * data[i].re + data[i].im * data[i].im; power[i] = data[i].re * data[i].re + data[i].im * data[i].im;
@ -1867,9 +1881,10 @@ struct cnr_fft : runnable
memcpy(avgpower, power, fft.n * sizeof(avgpower[0])); memcpy(avgpower, power, fft.n * sizeof(avgpower[0]));
} }
// Accumulate and low-pass filter // Accumulate and low-pass filter (exponential averaging)
for (int i = 0; i < fft.n; ++i) for (int i = 0; i < fft.n; ++i) {
avgpower[i] = avgpower[i] * (1 - kavg) + power[i] * kavg; avgpower[i] = avgpower[i] * (1 - kavg) + power[i] * kavg;
}
#if 0 #if 0
int bwslots = (bandwidth / 4) * fft.n; int bwslots = (bandwidth / 4) * fft.n;
@ -1888,12 +1903,10 @@ struct cnr_fft : runnable
int nstart = bandwidth * nslots_shift_ratio * fft.n; int nstart = bandwidth * nslots_shift_ratio * fft.n;
int nstop = nstart + bandwidth * nslots_ratio * fft.n; int nstop = nstart + bandwidth * nslots_ratio * fft.n;
if (!cbwslots || !nstart || !nstop) if (!cbwslots || !nstart || !nstop) {
{
delete[] power;
delete[] data;
return; return;
} }
// Measure carrier+noise in center band // Measure carrier+noise in center band
float c2plusn2 = avgslots(icf - cbwslots, icf + cbwslots); float c2plusn2 = avgslots(icf - cbwslots, icf + cbwslots);
// Measure noise left and right of roll-off zones // Measure noise left and right of roll-off zones
@ -1903,8 +1916,6 @@ struct cnr_fft : runnable
float c2 = c2plusn2 - n2; float c2 = c2plusn2 - n2;
float cnr = (c2 > 0 && n2 > 0) ? 10 * log10f(c2 / n2) : -50; float cnr = (c2 > 0 && n2 > 0) ? 10 * log10f(c2 / n2) : -50;
out.write(cnr); out.write(cnr);
delete[] power;
delete[] data;
} }
float avgslots(int i0, int i1) float avgslots(int i0, int i1)
@ -1921,6 +1932,8 @@ struct cnr_fft : runnable
pipewriter<float> out; pipewriter<float> out;
cfft_engine<T> fft; cfft_engine<T> fft;
T *avgpower; T *avgpower;
complex<T> *data;
T *power;
int phase; int phase;
float cslots_ratio; float cslots_ratio;
float nslots_shift_ratio; float nslots_shift_ratio;