From cc47718a2d6df0debb4cbf6725703cd410e38ed4 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Sat, 12 Nov 2016 14:07:58 +0000 Subject: [PATCH] Measure mean signal level in the converters. Rearrange the meaning of the measured power level to be consistent with the signal level. --- convert.c | 99 ++++++++++++++++++++++++++++++++++++---------------- convert.h | 3 +- demod_2400.c | 2 +- dump1090.c | 9 ++--- dump1090.h | 3 +- 5 files changed, 79 insertions(+), 37 deletions(-) diff --git a/convert.c b/convert.c index fec2526..0c02b72 100644 --- a/convert.c +++ b/convert.c @@ -30,11 +30,13 @@ static void convert_uc8_nodc(void *iq_data, uint16_t *mag_data, unsigned nsamples, struct converter_state *state, - double *out_power) + double *out_mean_level, + double *out_mean_power) { uint16_t *in = iq_data; unsigned i; - uint64_t power = 0; + uint64_t sum_level = 0; + uint64_t sum_power = 0; uint16_t mag; MODES_NOTUSED(state); @@ -43,45 +45,58 @@ static void convert_uc8_nodc(void *iq_data, for (i = 0; i < (nsamples>>3); ++i) { mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; } for (i = 0; i < (nsamples&7); ++i) { mag = Modes.maglut[*in++]; *mag_data++ = mag; - power += (uint32_t)mag * (uint32_t)mag; + sum_level += mag; + sum_power += (uint32_t)mag * (uint32_t)mag; } - if (out_power) { - *out_power = power / 65535.0 / 65535.0; + if (out_mean_level) { + *out_mean_level = sum_level / 65536.0 / nsamples; + } + + if (out_mean_power) { + *out_mean_power = sum_power / 65535.0 / 65535.0 / nsamples; } } @@ -89,10 +104,10 @@ static void convert_uc8_generic(void *iq_data, uint16_t *mag_data, unsigned nsamples, struct converter_state *state, - double *out_power) + double *out_mean_level, + double *out_mean_power) { uint8_t *in = iq_data; - float power = 0.0; float z1_I = state->z1_I; float z1_Q = state->z1_Q; const float dc_a = state->dc_a; @@ -101,6 +116,7 @@ static void convert_uc8_generic(void *iq_data, unsigned i; uint8_t I, Q; float fI, fQ, magsq; + float sum_level = 0, sum_power = 0; for (i = 0; i < nsamples; ++i) { I = *in++; @@ -118,25 +134,32 @@ static void convert_uc8_generic(void *iq_data, if (magsq > 1) magsq = 1; - power += magsq; - *mag_data++ = (uint16_t)(sqrtf(magsq) * 65535.0 + 0.5); + float mag = sqrtf(magsq); + sum_power += magsq; + sum_level += mag; + *mag_data++ = (uint16_t)(mag * 65535.0 + 0.5); } state->z1_I = z1_I; state->z1_Q = z1_Q; - if (out_power) - *out_power = power; + if (out_mean_level) { + *out_mean_level = sum_level / nsamples; + } + + if (out_mean_power) { + *out_mean_power = sum_power / nsamples; + } } static void convert_sc16_generic(void *iq_data, uint16_t *mag_data, unsigned nsamples, struct converter_state *state, - double *out_power) + double *out_mean_level, + double *out_mean_power) { uint16_t *in = iq_data; - float power = 0.0; float z1_I = state->z1_I; float z1_Q = state->z1_Q; const float dc_a = state->dc_a; @@ -145,6 +168,7 @@ static void convert_sc16_generic(void *iq_data, unsigned i; int16_t I, Q; float fI, fQ, magsq; + float sum_level = 0, sum_power = 0; for (i = 0; i < nsamples; ++i) { I = (int16_t)le16toh(*in++); @@ -162,25 +186,32 @@ static void convert_sc16_generic(void *iq_data, if (magsq > 1) magsq = 1; - power += magsq; - *mag_data++ = (uint16_t)(sqrtf(magsq) * 65535.0 + 0.5); + float mag = sqrtf(magsq); + sum_power += magsq; + sum_level += mag; + *mag_data++ = (uint16_t)(mag * 65535.0 + 0.5); } state->z1_I = z1_I; state->z1_Q = z1_Q; - if (out_power) - *out_power = power; + if (out_mean_level) { + *out_mean_level = sum_level / nsamples; + } + + if (out_mean_power) { + *out_mean_power = sum_power / nsamples; + } } static void convert_sc16q11_generic(void *iq_data, uint16_t *mag_data, unsigned nsamples, struct converter_state *state, - double *out_power) + double *out_mean_level, + double *out_mean_power) { uint16_t *in = iq_data; - float power = 0.0; float z1_I = state->z1_I; float z1_Q = state->z1_Q; const float dc_a = state->dc_a; @@ -189,6 +220,7 @@ static void convert_sc16q11_generic(void *iq_data, unsigned i; int16_t I, Q; float fI, fQ, magsq; + float sum_level = 0, sum_power = 0; for (i = 0; i < nsamples; ++i) { I = (int16_t)le16toh(*in++); @@ -206,15 +238,22 @@ static void convert_sc16q11_generic(void *iq_data, if (magsq > 1) magsq = 1; - power += magsq; + float mag = sqrtf(magsq); + sum_power += magsq; + sum_level += mag; *mag_data++ = (uint16_t)(sqrtf(magsq) * 65535.0 + 0.5); } state->z1_I = z1_I; state->z1_Q = z1_Q; - if (out_power) - *out_power = power; + if (out_mean_level) { + *out_mean_level = sum_level / nsamples; + } + + if (out_mean_power) { + *out_mean_power = sum_power / nsamples; + } } static struct { diff --git a/convert.h b/convert.h index 2bf806b..6412fc0 100644 --- a/convert.h +++ b/convert.h @@ -27,7 +27,8 @@ typedef void (*iq_convert_fn)(void *iq_data, uint16_t *mag_data, unsigned nsamples, struct converter_state *state, - double *out_power); + double *out_mean_level, + double *out_mean_power); iq_convert_fn init_converter(input_format_t format, double sample_rate, diff --git a/demod_2400.c b/demod_2400.c index 35b45bd..5fdefca 100644 --- a/demod_2400.c +++ b/demod_2400.c @@ -360,7 +360,7 @@ void demodulate2400(struct mag_buf *mag) /* update noise power */ { double sum_signal_power = sum_scaled_signal_power / 65535.0 / 65535.0; - Modes.stats_current.noise_power_sum += (mag->total_power - sum_signal_power); + Modes.stats_current.noise_power_sum += (mag->mean_power * mag->length - sum_signal_power); Modes.stats_current.noise_power_count += mag->length; } } diff --git a/dump1090.c b/dump1090.c index 3561c7c..85161a3 100644 --- a/dump1090.c +++ b/dump1090.c @@ -246,9 +246,10 @@ void modesInit(void) { static void convert_samples(void *iq, uint16_t *mag, unsigned nsamples, - double *power) + double *mean_level, + double *mean_power) { - Modes.converter_function(iq, mag, nsamples, Modes.converter_state, power); + Modes.converter_function(iq, mag, nsamples, Modes.converter_state, mean_level, mean_power); } // @@ -445,7 +446,7 @@ void rtlsdrCallback(unsigned char *buf, uint32_t len, void *ctx) { // Convert the new data outbuf->length = slen; - convert_samples(buf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->total_power); + convert_samples(buf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->mean_level, &outbuf->mean_power); // Push the new data to the demodulation thread pthread_mutex_lock(&Modes.data_mutex); @@ -538,7 +539,7 @@ void readDataFromFile(void) { slen = outbuf->length = MODES_MAG_BUF_SAMPLES - toread/bytes_per_sample; // Convert the new data - convert_samples(readbuf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->total_power); + convert_samples(readbuf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->mean_level, &outbuf->mean_power); if (Modes.throttle) { // Wait until we are allowed to release this buffer to the main thread diff --git a/dump1090.h b/dump1090.h index 9c4a79c..c50bfd9 100644 --- a/dump1090.h +++ b/dump1090.h @@ -255,7 +255,8 @@ struct mag_buf { uint64_t sampleTimestamp; // Clock timestamp of the start of this block, 12MHz clock struct timespec sysTimestamp; // Estimated system time at start of block uint32_t dropped; // Number of dropped samples preceding this buffer - double total_power; // Sum of per-sample input power (in the range [0.0,1.0] per sample), or 0 if not measured + double mean_level; // Mean of normalized (0..1) signal level + double mean_power; // Mean of normalized (0..1) power level }; // Program global state