From 451243b3812977c9bb41a32b1593a418b2b36a81 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 14 Mar 2021 18:57:31 +0100 Subject: [PATCH] DATV: estimate CNR with average of 20% highest and lowest powers in 1.5 times SR bandwidth --- plugins/channelrx/demoddatv/leansdr/sdr.h | 35 +++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/plugins/channelrx/demoddatv/leansdr/sdr.h b/plugins/channelrx/demoddatv/leansdr/sdr.h index 6a101a20f..d2b2e8bb9 100644 --- a/plugins/channelrx/demoddatv/leansdr/sdr.h +++ b/plugins/channelrx/demoddatv/leansdr/sdr.h @@ -17,6 +17,8 @@ #ifndef LEANSDR_SDR_H #define LEANSDR_SDR_H +#include + #include "leansdr/dsp.h" #include "leansdr/math.h" @@ -1809,6 +1811,7 @@ struct cnr_fft : runnable out(_out), fft(nfft), avgpower(nullptr), + sorted(nullptr), data(nullptr), power(nullptr), phase(0), @@ -1827,6 +1830,9 @@ struct cnr_fft : runnable if (avgpower) { delete[] avgpower; } + if (sorted) { + delete[] sorted; + } if (data) { delete[] data; } @@ -1859,6 +1865,9 @@ struct cnr_fft : runnable private: void do_cnr() { + if (!sorted) { + sorted = new T[fft.n]; + } if (!data) { data = new complex[fft.n]; } @@ -1886,7 +1895,8 @@ struct cnr_fft : runnable avgpower[i] = avgpower[i] * (1 - kavg) + power[i] * kavg; } -#if 0 +#define LEANDVB_SDR_CNR_METHOD 2 +#if LEANDVB_SDR_CNR_METHOD == 0 int bwslots = (bandwidth / 4) * fft.n; if (!bwslots) { @@ -1898,7 +1908,7 @@ struct cnr_fft : runnable // Measure noise left and right of roll-off zones float n2 = ( avgslots(icf-bwslots*4, icf-bwslots*3) + avgslots(icf+bwslots*3, icf+bwslots*4) ) / 2; -#else +#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; @@ -1912,6 +1922,11 @@ struct cnr_fft : runnable // Measure noise left and right of roll-off zones 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; + float c2plusn2 = 0; + float n2 = 0; + minmax(icf - bw, icf + bw, n2, c2plusn2); #endif float c2 = c2plusn2 - n2; float cnr = (c2 > 0 && n2 > 0) ? 10 * log10f(c2 / n2) : -50; @@ -1928,10 +1943,26 @@ struct cnr_fft : runnable return s / (i1 - i0 + 1); } + void minmax(int i0, int i1, float& min, float&max) + { + int l = 0; + + for (int i = i0; i <= i1; ++i, ++l) + sorted[l] = avgpower[i & (fft.n - 1)]; + + std::sort(sorted, &sorted[l]); + int m = l/5; + min = std::accumulate(&sorted[0], &sorted[m], (T) 0) / (m+1); + max = std::accumulate(&sorted[l-m], &sorted[l], (T) 0) / (m+1); + + // fprintf(stderr, "l: %d m: %d min: %f max: %f\n", l, m, min, max); + } + pipereader> in; pipewriter out; cfft_engine fft; T *avgpower; + T *sorted; complex *data; T *power; int phase;