getbits.c - acarsdec - an ACARS decoder
 (HTM) git clone git://r-36.net/acarsdec
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) 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 }