From 227245eb94d8bc791c4362137de61f7919f3b9ef Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 14 Mar 2021 10:54:37 +0100 Subject: [PATCH] DATV: CNR optimization --- plugins/channelrx/demoddatv/datvdemodsink.cpp | 4 +-- plugins/channelrx/demoddatv/leansdr/sdr.h | 35 +++++++++++++------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/plugins/channelrx/demoddatv/datvdemodsink.cpp b/plugins/channelrx/demoddatv/datvdemodsink.cpp index 1baaf4ad8..4eee1bd06 100644 --- a/plugins/channelrx/demoddatv/datvdemodsink.cpp +++ b/plugins/channelrx/demoddatv/datvdemodsink.cpp @@ -668,7 +668,7 @@ void DATVDemodSink::InitDATVFramework() if (m_objCfg.cnr == true) { - r_cnr = new leansdr::cnr_fft(m_objScheduler, *p_preprocessed, *p_cnr, m_objCfg.Fm/m_objCfg.Fs); + r_cnr = new leansdr::cnr_fft(m_objScheduler, *p_preprocessed, *p_cnr, m_objCfg.Fm/m_objCfg.Fs, 1024); r_cnr->decimation = decimation(m_objCfg.Fs, 5); // 5 Hz } @@ -1000,7 +1000,7 @@ void DATVDemodSink::InitDATVS2Framework() if (m_objCfg.cnr == true) { - r_cnr = new leansdr::cnr_fft(m_objScheduler, *p_preprocessed, *p_cnr, m_objCfg.Fm/m_objCfg.Fs); + r_cnr = new leansdr::cnr_fft(m_objScheduler, *p_preprocessed, *p_cnr, m_objCfg.Fm/m_objCfg.Fs, 1024); r_cnr->decimation = decimation(m_objCfg.Fs, 5); // 5 Hz } diff --git a/plugins/channelrx/demoddatv/leansdr/sdr.h b/plugins/channelrx/demoddatv/leansdr/sdr.h index 8c4cce61c..6a101a20f 100644 --- a/plugins/channelrx/demoddatv/leansdr/sdr.h +++ b/plugins/channelrx/demoddatv/leansdr/sdr.h @@ -1796,7 +1796,8 @@ struct cnr_fft : runnable scheduler *sch, pipebuf> &_in, pipebuf &_out, - float _bandwidth, int nfft = 4096 + float _bandwidth, + int nfft = 4096 ) : runnable(sch, "cnr_fft"), bandwidth(_bandwidth), @@ -1808,6 +1809,8 @@ struct cnr_fft : runnable out(_out), fft(nfft), avgpower(nullptr), + data(nullptr), + power(nullptr), phase(0), cslots_ratio(0.2), nslots_shift_ratio(0.65), @@ -1824,6 +1827,12 @@ struct cnr_fft : runnable if (avgpower) { delete[] avgpower; } + if (data) { + delete[] data; + } + if (power) { + delete[] power; + } } void run() @@ -1850,12 +1859,17 @@ struct cnr_fft : runnable private: void do_cnr() { + if (!data) { + data = new complex[fft.n]; + } + if (!power) { + power = new T[fft.n]; + } + float center_freq = freq_tap ? *freq_tap * tap_multiplier : 0; int icf = floor(center_freq * fft.n + 0.5); - complex *data = new complex[fft.n]; memcpy(data, in.rd(), fft.n * sizeof(data[0])); fft.inplace(data, true); - T *power = new T[fft.n]; for (int i = 0; i < fft.n; ++i) 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])); } - // Accumulate and low-pass filter - for (int i = 0; i < fft.n; ++i) + // Accumulate and low-pass filter (exponential averaging) + for (int i = 0; i < fft.n; ++i) { avgpower[i] = avgpower[i] * (1 - kavg) + power[i] * kavg; + } #if 0 int bwslots = (bandwidth / 4) * fft.n; @@ -1888,12 +1903,10 @@ struct cnr_fft : runnable int nstart = bandwidth * nslots_shift_ratio * fft.n; int nstop = nstart + bandwidth * nslots_ratio * fft.n; - if (!cbwslots || !nstart || !nstop) - { - delete[] power; - delete[] data; + if (!cbwslots || !nstart || !nstop) { return; } + // Measure carrier+noise in center band float c2plusn2 = avgslots(icf - cbwslots, icf + cbwslots); // Measure noise left and right of roll-off zones @@ -1903,8 +1916,6 @@ struct cnr_fft : runnable float c2 = c2plusn2 - n2; float cnr = (c2 > 0 && n2 > 0) ? 10 * log10f(c2 / n2) : -50; out.write(cnr); - delete[] power; - delete[] data; } float avgslots(int i0, int i1) @@ -1921,6 +1932,8 @@ struct cnr_fft : runnable pipewriter out; cfft_engine fft; T *avgpower; + complex *data; + T *power; int phase; float cslots_ratio; float nslots_shift_ratio;