From a9945ffaa3d14def8b3b56900d2dfba2184b8516 Mon Sep 17 00:00:00 2001 From: Clifford Heath Date: Mon, 14 Jun 2021 03:59:26 +1000 Subject: [PATCH] Report amplitude once per second during receive (#890) * Report amplitude once per second during receive * Added missing M_LN10 for Windoze, fixed short frame detection for RSSI * Tweaks to math expressions * Tweaks to math expressions --- host/hackrf-tools/src/hackrf_transfer.c | 39 ++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index fda6faf5..a4db1904 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -336,6 +337,17 @@ uint32_t stream_tail = 0; uint32_t stream_drop = 0; uint8_t *stream_buf = NULL; +/* + * To report amplitude, best would be dB(fullscale) and the variance, + * but that would require more math per sample (dB(amplitude) = log(sqrt(i^2 + q^2) and sum of squares). + * For now, just sum iabs(i)+iabs(q) and divide by the number of samples*2. + * That allows us to give a measure of dB(fullscale). + * I don't know whether overload causes wrapping or clamping the 8-bit values. + * Clamping would produce a sigmoid curve, so with a signal of variable intensity you're + * probably getting substantial overload anytime this reports more than about -6dBfs. + */ +uint64_t stream_amplitude = 0; /* sum of magnitudes of all I&Q samples, reset on the periodic report */ + bool transmit = false; struct timeval time_start; struct timeval t_start; @@ -390,6 +402,12 @@ int rx_callback(hackrf_transfer* transfer) { } bytes_to_xfer -= bytes_to_write; } + + // accumulate stream_amplitude: + for (i = 0; i < bytes_to_write; i++) { + stream_amplitude += abs((signed char)transfer->buffer[i]); + } + if (receive_wav) { /* convert .wav contents from signed to unsigned */ for (i = 0; i < bytes_to_write; i++) { @@ -1058,20 +1076,33 @@ int main(int argc, char** argv) { } #endif } else { + uint64_t stream_amplitude_now; sleep(1); gettimeofday(&time_now, NULL); byte_count_now = byte_count; byte_count = 0; - - + stream_amplitude_now = stream_amplitude; + stream_amplitude = 0; + if (byte_count_now < sample_rate_hz/20) // Don't report on very short frames + stream_amplitude_now = 0; + time_difference = TimevalDiff(&time_now, &time_start); rate = (float)byte_count_now / time_difference; if (byte_count_now == 0 && hw_sync == true && hw_sync_enable != 0) { fprintf(stderr, "Waiting for sync...\n"); } else { - fprintf(stderr, "%4.1f MiB / %5.3f sec = %4.1f MiB/second\n", - (byte_count_now / 1e6f), time_difference, (rate / 1e6f) ); + // This is only an approximate measure, to assist getting receive levels right: + double full_scale_ratio = ((double)stream_amplitude_now / (byte_count_now ? byte_count_now : 1))/128; + double dB_full_scale_ratio = 10*log10(full_scale_ratio); + if (dB_full_scale_ratio > 1) + dB_full_scale_ratio = NAN; // Guard against ridiculous reports + fprintf(stderr, "%4.1f MiB / %5.3f sec = %4.1f MiB/second, amplitude %3.1f dBfs\n", + (byte_count_now / 1e6f), + time_difference, + (rate / 1e6f), + dB_full_scale_ratio + ); } time_start = time_now;