From f258b1d7d7845f14f04a14e80400221242821c7e Mon Sep 17 00:00:00 2001 From: sq5bpf Date: Tue, 2 Aug 2022 15:30:28 +0200 Subject: [PATCH] Added basic AFC as implemented by SQ5BPF into float_to_bits.c The AFC implementation by SQ5BPF as used in his fork of osmo-tetra significantly increases reception quality. A simple test yields 14545 valid CRCs as opposed to 11934 when AFC is not used. I added the AFC to float_to_bits, the functionality can be activated with the -a flag. Change-Id: I1c9343b83739108a1e423c4880e1dc7964656529 --- src/float_to_bits.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/float_to_bits.c b/src/float_to_bits.c index 9ececa0..89d0421 100644 --- a/src/float_to_bits.c +++ b/src/float_to_bits.c @@ -73,25 +73,47 @@ static void sym_int2bits(int sym, uint8_t *ret) // size of IO buffers (number of elements) #define BUF_SIZE 1024 +#define MAXVAL 5.0 + int main(int argc, char **argv) { int fd, fd_out, opt; - int opt_verbose = 0; + int opt_afc = 0; - while ((opt = getopt(argc, argv, "v")) != -1) { + float filter = 0; + float filter_val = 0.0001; + float filter_goal = 0; + int sym; + + + while ((opt = getopt(argc, argv, "vaf:F:")) != -1) { switch (opt) { case 'v': opt_verbose = 1; break; + case 'a': + opt_afc = 1; + break; + case 'f': + filter_val = atof(optarg); + break; + case 'F': + filter_goal = atof(optarg); + break; + default: exit(2); } } if (argc <= optind+1) { - fprintf(stderr, "Usage: %s [-v] \n", argv[0]); + fprintf(stderr, "Usage: %s [-v] [-a] [-f filter_val] [-F filter_goal] \n", argv[0]); + fprintf(stderr, "-v verbose, print bits to stdout\n"); + fprintf(stderr, "-a turn on pseudo-afc (automatic frequency correction)\n"); + fprintf(stderr, "-f pseudo-afc averaging filter constant (default 0.0001)\n"); + fprintf(stderr, "-F pseudo-afc filter goal (default: 0)\n"); exit(2); } @@ -119,7 +141,16 @@ int main(int argc, char **argv) rc /= sizeof(*fl); int i; for (i = 0; i < rc; ++i) { - int sym = process_sym_fl(fl[i]); + + if ((fl[i] > -MAXVAL) && (fl[i] < MAXVAL)) { + filter = filter * (1.0 - filter_val) + (fl[i] - filter_goal) * filter_val; + } + if (opt_afc) { + sym = process_sym_fl(fl[i]-filter); + } else { + sym = process_sym_fl(fl[i]); + } + sym_int2bits(sym, bits + i*2); //printf("%2d %1u %1u %f\n", rc, bits[0], bits[1], fl); if (opt_verbose) {