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
This commit is contained in:
Clifford Heath
2021-06-14 03:59:26 +10:00
committed by GitHub
parent 34b614f933
commit a9945ffaa3

View File

@ -29,6 +29,7 @@
#include <string.h> #include <string.h>
#include <getopt.h> #include <getopt.h>
#include <time.h> #include <time.h>
#include <math.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -336,6 +337,17 @@ uint32_t stream_tail = 0;
uint32_t stream_drop = 0; uint32_t stream_drop = 0;
uint8_t *stream_buf = NULL; 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; bool transmit = false;
struct timeval time_start; struct timeval time_start;
struct timeval t_start; struct timeval t_start;
@ -390,6 +402,12 @@ int rx_callback(hackrf_transfer* transfer) {
} }
bytes_to_xfer -= bytes_to_write; 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) { if (receive_wav) {
/* convert .wav contents from signed to unsigned */ /* convert .wav contents from signed to unsigned */
for (i = 0; i < bytes_to_write; i++) { for (i = 0; i < bytes_to_write; i++) {
@ -1058,20 +1076,33 @@ int main(int argc, char** argv) {
} }
#endif #endif
} else { } else {
uint64_t stream_amplitude_now;
sleep(1); sleep(1);
gettimeofday(&time_now, NULL); gettimeofday(&time_now, NULL);
byte_count_now = byte_count; byte_count_now = byte_count;
byte_count = 0; 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); time_difference = TimevalDiff(&time_now, &time_start);
rate = (float)byte_count_now / time_difference; rate = (float)byte_count_now / time_difference;
if (byte_count_now == 0 && hw_sync == true && hw_sync_enable != 0) { if (byte_count_now == 0 && hw_sync == true && hw_sync_enable != 0) {
fprintf(stderr, "Waiting for sync...\n"); fprintf(stderr, "Waiting for sync...\n");
} else { } else {
fprintf(stderr, "%4.1f MiB / %5.3f sec = %4.1f MiB/second\n", // This is only an approximate measure, to assist getting receive levels right:
(byte_count_now / 1e6f), time_difference, (rate / 1e6f) ); 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; time_start = time_now;