acarsdec/getbits.c

192 lines
4.3 KiB
C

/*
* Copyright (c) 2007 by Thierry Leconte (F4DWV)
*
* $Id: getbits.c,v 1.4 2007/04/15 15:06:54 f4dwv Exp $
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "acarsdec.h"
#define Fe 48000.0
#define Freqh 4800.0/Fe*2.0*M_PI
#define Freql 2400.0/Fe*2.0*M_PI
#define BITLEN ((int)Fe/1200)
static float h[BITLEN];
static struct bstat_s {
float hsample[BITLEN];
float lsample[BITLEN];
float isample[BITLEN];
float qsample[BITLEN];
float csample[BITLEN];
int is;
int clock;
float lin;
float phih,phil;
float dfh,dfl;
float pC,ppC;
int sgI, sgQ;
float ea;
} bstat[2];
void init_bits(void)
{
int i;
for (i = 0; i < BITLEN; i++)
h[i] = sin(2.0 * M_PI * (float) i / (float) BITLEN);
for (i = 0; i < BITLEN; i++) {
bstat[0].hsample[i] = bstat[0].lsample[i] =
bstat[0].isample[i] = bstat[0].qsample[i] =
bstat[0].csample[i] = 0.0;
bstat[1].hsample[i] = bstat[1].lsample[i] =
bstat[1].isample[i] = bstat[1].qsample[i] =
bstat[1].csample[i] = 0.0;
}
bstat[0].is = bstat[0].clock = bstat[0].sgI = bstat[0].sgQ = 0;
bstat[1].is = bstat[1].clock = bstat[1].sgI = bstat[1].sgQ = 0;
bstat[0].phih = bstat[0].phil = bstat[0].dfh = bstat[0].dfl =
bstat[0].pC = bstat[0].ppC = bstat[0].ea = 0.0;
bstat[1].phih = bstat[1].phil = bstat[1].dfh = bstat[1].dfl =
bstat[1].pC = bstat[1].ppC = bstat[1].ea = 0.0;
bstat[0].lin=bstat[1].lin=1.0;
}
void resetbits(int ch)
{
bstat[ch].sgI = bstat[ch].sgQ = 0;
}
#define VFOPLL 0.7e-3
#define BITPLL 0.2
int getbit(short sample, unsigned char *outbits, int ch)
{
int i, bt;
float in, in2;
float C;
float I, Q;
float oscl, osch;
struct bstat_s *st;
bt = 0;
st = &bstat[ch];
in = (float) sample;
st->lin = 0.003 * fabs(in) + 0.997 * st->lin;
in /= st->lin;
in2 = in * in;
st->is--;
if (st->is < 0)
st->is = BITLEN - 1;
/* VFOs */
st->phih += Freqh - VFOPLL * st->dfh;
if (st->phih >= 4.0 * M_PI)
st->phih -= 4.0 * M_PI;
st->hsample[st->is] = in2 * sin(st->phih);
for (i = 0, st->dfh = 0.0; i < BITLEN / 2; i++) {
st->dfh += st->hsample[(st->is + i) % BITLEN];
}
osch = cos(st->phih / 2.0);
st->phil += Freql - VFOPLL * st->dfl;
if (st->phil >= 4.0 * M_PI)
st->phil -= 4.0 * M_PI;
st->lsample[st->is] = in2 * sin(st->phil);
for (i = 0, st->dfl = 0.0; i < BITLEN / 2; i++) {
st->dfl += st->lsample[(st->is + i) % BITLEN];
}
oscl = cos(st->phil / 2.0);
/* mix */
st->isample[st->is] = in * (oscl + osch);
st->qsample[st->is] = in * (oscl - osch);
st->csample[st->is] = oscl * osch;
/* bit clock */
st->clock++;
if (st->clock >= BITLEN/4 + st->ea) {
st->clock = 0;
/* clock filter */
for (i = 0, C = 0.0; i < BITLEN; i++) {
C += h[i] * st->csample[(st->is + i) % BITLEN];
}
if (st->pC < C && st->pC < st->ppC) {
/* integrator */
for (i = 0, Q = 0.0; i < BITLEN; i++) {
Q += st->qsample[(st->is + i) % BITLEN];
}
if (st->sgQ == 0) {
if (Q < 0)
st->sgQ = -1;
else
st->sgQ = 1;
}
*outbits =
((*outbits) >> 1) | (unsigned
char) ((Q * st->sgQ >
0) ? 0x80 : 0);
bt = 1;
st->ea = -BITPLL * (C - st->ppC);
if(st->ea > 2.0) st->ea=2.0;
if(st->ea < -2.0) st->ea=-2.0;
}
if (st->pC > C && st->pC > st->ppC) {
/* integrator */
for (i = 0, I = 0.0; i < BITLEN; i++) {
I += st->isample[(st->is + i) % BITLEN];
}
if (st->sgI == 0) {
if (I < 0)
st->sgI = -1;
else
st->sgI = 1;
}
*outbits =
((*outbits) >> 1) | (unsigned
char) ((I * st->sgI >
0) ? 0x80 : 0);
bt = 1;
st->ea = BITPLL * (C - st->ppC);
if(st->ea > 2.0) st->ea=2.0;
if(st->ea < -2.0) st->ea=-2.0;
}
st->ppC = st->pC;
st->pC = C;
}
return bt;
}