crude pseudo AFC for float_to_bits

Jacek Lipkowski sq5bpf at lipkowski.org
Wed Feb 3 11:44:04 UTC 2016


Hello

I've added a very crude pseudo AFC to float_to_bits. It uses an averaging 
filter on the input values, and compensates for any fixed offset it finds 
in the input data (if all bit combinations are equally likely to appear in 
the input stream, then a long-term average should be 0).

This helps a bit when decoding a mistuned signal (due to receiver 
frequency drift etc). From a quick test yesterday normally the receiver 
works when the signal is mistuned from -1.6 to 1.3kHz, with the -a option 
the receiver works when the signal is mistuned from -2.8 to 2kHz.

Diff included, or source here:
https://github.com/sq5bpf/osmo-tetra-sq5bpf/blob/master/src/float_to_bits.c


Jacek
-------------- next part --------------
Crude AFC option to improve reception of mistuned signals --sq5bpf

--- float_to_bits.c.orig	2016-02-03 10:33:12.579962767 +0100
+++ float_to_bits.c	2016-02-03 11:29:57.384588114 +0100
@@ -17,6 +17,7 @@
  * You should have received a copy of the GNU Affero General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
+ * 20160203: added crude AFC option --sq5bpf
  */
 
 
@@ -76,19 +77,29 @@
 	int fd, fd_out, opt;
 
 	int opt_verbose = 0;
+	int do_afc=0;
+	float filter=0;
+	float filter_val=0.0001;
+	int ccounter=0;
 
-	while ((opt = getopt(argc, argv, "v")) != -1) {
+	while ((opt = getopt(argc, argv, "vaf:F:")) != -1) {
 		switch (opt) {
-		case 'v':
-			opt_verbose = 1;
-			break;
-		default:
-			exit(2);
+			case 'v':
+				opt_verbose++;
+				break;
+			case 'a':
+				do_afc=1;
+				break;
+			case 'f':
+				filter_val=atof(optarg);
+				break;
+			default:
+				exit(2);
 		}
 	}
 
 	if (argc <= optind+1) {
-		fprintf(stderr, "Usage: %s [-v] <infile> <outfile>\n", argv[0]);
+		fprintf(stderr, "Usage: %s [-v] [-a] [-f filter_averaging_coefficient] <infile> <outfile>\n", argv[0]);
 		exit(2);
 	}
 
@@ -112,12 +123,20 @@
 			exit(1);
 		} else if (rc == 0)
 			break;
+#define MAXVAL 5.0 /* this is the maximum value we'll accept for the incoming floats */
+		if ((fl>-MAXVAL)&&(fl<MAXVAL))
+			filter=filter*(1.0-filter_val)+fl*filter_val;
+		if (do_afc) fl=fl-filter;
+
 		rc = process_sym_fl(fl);
 		sym_int2bits(rc, bits);
 		//printf("%2d %1u %1u  %f\n", rc, bits[0], bits[1], fl);
 		if (opt_verbose)
 			printf("%1u%1u", bits[0], bits[1]);
-
+		if ((do_afc)&&(opt_verbose>1)) {
+			ccounter++;
+			if (ccounter>50) { printf(" AFC: %f\n",filter); ccounter=0; }
+		}
 		rc = write(fd_out, bits, 2);
 		if (rc < 0) {
 			perror("write");


More information about the tetra mailing list