acarsdec

an ACARS decoder
git clone git://r-36.net/acarsdec
Log | Files | Refs | README

getbits.c (4418B)


      1 /*
      2  *  Copyright (c) 2007 by Thierry Leconte (F4DWV)
      3  *
      4  *      $Id: getbits.c,v 1.4 2007/04/15 15:06:54 f4dwv Exp $
      5  *
      6  *   This code is free software; you can redistribute it and/or modify
      7  *   it under the terms of the GNU Library General Public License version 2
      8  *   published by the Free Software Foundation.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *   GNU Library General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU Library General Public
     16  *   License along with this library; if not, write to the Free Software
     17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18  *
     19  */
     20 
     21 #include <stdlib.h>
     22 #include <stdio.h>
     23 #include <math.h>
     24 
     25 #include "acarsdec.h"
     26 
     27 
     28 #define Fe 48000.0
     29 #define Freqh 4800.0/Fe*2.0*M_PI
     30 #define Freql 2400.0/Fe*2.0*M_PI
     31 #define BITLEN ((int)Fe/1200)
     32 
     33 static float h[BITLEN];
     34 
     35 static struct bstat_s {
     36 	float hsample[BITLEN];
     37 	float lsample[BITLEN];
     38 	float isample[BITLEN];
     39 	float qsample[BITLEN];
     40 	float csample[BITLEN];
     41 	int is;
     42 	int clock;
     43 	float lin;
     44 	float phih,phil;
     45 	float dfh,dfl;
     46 	float pC,ppC;
     47 	int sgI, sgQ;
     48 	float ea;
     49 } bstat[2];
     50 
     51 
     52 void init_bits(void)
     53 {
     54 	int i;
     55 	for (i = 0; i < BITLEN; i++)
     56 		h[i] = sin(2.0 * M_PI * (float) i / (float) BITLEN);
     57 
     58 	for (i = 0; i < BITLEN; i++) {
     59 		bstat[0].hsample[i] = bstat[0].lsample[i] =
     60 		    bstat[0].isample[i] = bstat[0].qsample[i] =
     61 		    bstat[0].csample[i] = 0.0;
     62 		bstat[1].hsample[i] = bstat[1].lsample[i] =
     63 		    bstat[1].isample[i] = bstat[1].qsample[i] =
     64 		    bstat[1].csample[i] = 0.0;
     65 	}
     66 	bstat[0].is = bstat[0].clock = bstat[0].sgI = bstat[0].sgQ = 0;
     67 	bstat[1].is = bstat[1].clock = bstat[1].sgI = bstat[1].sgQ = 0;
     68 	bstat[0].phih = bstat[0].phil = bstat[0].dfh = bstat[0].dfl =
     69 	    bstat[0].pC = bstat[0].ppC = bstat[0].ea = 0.0;
     70 	bstat[1].phih = bstat[1].phil = bstat[1].dfh = bstat[1].dfl =
     71 	    bstat[1].pC = bstat[1].ppC = bstat[1].ea = 0.0;
     72 	bstat[0].lin=bstat[1].lin=1.0;
     73 
     74 }
     75 
     76 void resetbits(int ch)
     77 {
     78 	bstat[ch].sgI = bstat[ch].sgQ = 0;
     79 }
     80 
     81 #define VFOPLL 0.7e-3
     82 #define BITPLL 0.2
     83 
     84 int getbit(short sample, unsigned char *outbits, int ch)
     85 {
     86 	int i, bt;
     87 	float in, in2;
     88 	float C;
     89 	float I, Q;
     90 	float oscl, osch;
     91 	struct bstat_s *st;
     92 
     93 	bt = 0;
     94 	st = &bstat[ch];
     95 
     96 	in = (float) sample;
     97 	st->lin = 0.003 * fabs(in) + 0.997 * st->lin;
     98 	in /= st->lin;
     99 	in2 = in * in;
    100 
    101 	st->is--;
    102 	if (st->is < 0)
    103 		st->is = BITLEN - 1;
    104 
    105 	/* VFOs */
    106 	st->phih += Freqh - VFOPLL * st->dfh;
    107 	if (st->phih >= 4.0 * M_PI)
    108 		st->phih -= 4.0 * M_PI;
    109 	st->hsample[st->is] = in2 * sin(st->phih);
    110 	for (i = 0, st->dfh = 0.0; i < BITLEN / 2; i++) {
    111 		st->dfh += st->hsample[(st->is + i) % BITLEN];
    112 	}
    113 	osch = cos(st->phih / 2.0);
    114 
    115 	st->phil += Freql - VFOPLL * st->dfl;
    116 	if (st->phil >= 4.0 * M_PI)
    117 		st->phil -= 4.0 * M_PI;
    118 	st->lsample[st->is] = in2 * sin(st->phil);
    119 	for (i = 0, st->dfl = 0.0; i < BITLEN / 2; i++) {
    120 		st->dfl += st->lsample[(st->is + i) % BITLEN];
    121 	}
    122 	oscl = cos(st->phil / 2.0);
    123 
    124 	/* mix */
    125 	st->isample[st->is] = in * (oscl + osch);
    126 	st->qsample[st->is] = in * (oscl - osch);
    127 	st->csample[st->is] = oscl * osch;
    128 
    129 
    130 	/* bit clock */
    131 	st->clock++;
    132 	if (st->clock >= BITLEN/4 + st->ea) {
    133 		st->clock = 0;
    134 
    135 		/*  clock filter  */
    136 		for (i = 0, C = 0.0; i < BITLEN; i++) {
    137 			C += h[i] * st->csample[(st->is + i) % BITLEN];
    138 		}
    139 
    140 		if (st->pC < C && st->pC < st->ppC) {
    141 
    142 			/* integrator */
    143 			for (i = 0, Q = 0.0; i < BITLEN; i++) {
    144 				Q += st->qsample[(st->is + i) % BITLEN];
    145 			}
    146 
    147 			if (st->sgQ == 0) {
    148 				if (Q < 0)
    149 					st->sgQ = -1;
    150 				else
    151 					st->sgQ = 1;
    152 			}
    153 
    154 			*outbits =
    155 			    ((*outbits) >> 1) | (unsigned
    156 						 char) ((Q * st->sgQ >
    157 							 0) ? 0x80 : 0);
    158 			bt = 1;
    159 
    160 			st->ea = -BITPLL * (C - st->ppC);
    161 			if(st->ea > 2.0) st->ea=2.0;
    162 			if(st->ea < -2.0) st->ea=-2.0;
    163 		}
    164 		if (st->pC > C && st->pC > st->ppC) {
    165 
    166 			/* integrator */
    167 			for (i = 0, I = 0.0; i < BITLEN; i++) {
    168 				I += st->isample[(st->is + i) % BITLEN];
    169 			}
    170 
    171 			if (st->sgI == 0) {
    172 				if (I < 0)
    173 					st->sgI = -1;
    174 				else
    175 					st->sgI = 1;
    176 			}
    177 
    178 			*outbits =
    179 			    ((*outbits) >> 1) | (unsigned
    180 						 char) ((I * st->sgI >
    181 							 0) ? 0x80 : 0);
    182 			bt = 1;
    183 
    184 			st->ea = BITPLL * (C - st->ppC);
    185 			if(st->ea > 2.0) st->ea=2.0;
    186 			if(st->ea < -2.0) st->ea=-2.0;
    187 		}
    188 		st->ppC = st->pC;
    189 		st->pC = C;
    190 	}
    191 	return bt;
    192 }