Change the fsk filter used in CID and TDD decode to an integer based implementation

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@78227 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Doug Bailey
2007-08-06 19:52:40 +00:00
parent 8f17952065
commit 3e426df072
4 changed files with 213 additions and 190 deletions

View File

@@ -31,30 +31,39 @@
#define NCOLA 0x4000 #define NCOLA 0x4000
/* new filter structure */
struct filter_struct {
int icoefs[8];
int ip;
int ixv[8];
int iyv[8];
};
typedef struct { typedef struct {
float spb; /*!< Samples / Bit */
int nbit; /*!< Number of Data Bits (5,7,8) */ int nbit; /*!< Number of Data Bits (5,7,8) */
float nstop; /*!< Number of Stop Bits 1,1.5,2 */
int parity; /*!< Parity 0=none 1=even 2=odd */ int parity; /*!< Parity 0=none 1=even 2=odd */
int instop; /*!< Number of Stop Bits */
int hdlc; /*!< Modo Packet */ int hdlc; /*!< Modo Packet */
float x0; int xi0;
float x1; int xi1;
float x2; int xi2;
float cont;
int bw; /*!< Bandwidth */ int ispb;
double fmxv[8],fmyv[8]; /*!< filter stuff for M filter */ int icont;
int fmp; /*!< pointer for M filter */ int bw; /*!< Band Selector*/
double fsxv[8],fsyv[8]; /*!< filter stuff for S filter */ int f_mark_idx; /*!< Mark Frequency Index (f_M-500)/5 */
int fsp; /*!< pointer for S filter */ int f_space_idx; /*!< Space Frequency Index (f_S-500)/5 */
double flxv[8],flyv[8]; /*!< filter stuff for L filter */
int flp; /*!< pointer for L filter */
int f_mark_idx; /*!< Mark frequency index (f_M-500)/5 */
int f_space_idx; /*!< Space frequency index (f_S-500)/5 */
int state; int state;
int pcola; /*!< Pointer to data queues */
float cola_in[NCOLA]; /*!< Queue of input samples */ int pllispb; /*!<Pll autosense */
float cola_filter[NCOLA]; /*!< Queue of samples after filters */ int pllids;
float cola_demod[NCOLA]; /*!< Queue of demodulated samples */ int pllispb2;
struct filter_struct mark_filter;
struct filter_struct space_filter;
struct filter_struct demod_filter;
} fsk_data; } fsk_data;
/* \brief Retrieve a serial byte into outbyte. /* \brief Retrieve a serial byte into outbyte.
@@ -65,7 +74,8 @@ typedef struct {
\arg 0: Still looking for something... \arg 0: Still looking for something...
\arg 1: An output byte was received and stored in outbyte \arg 1: An output byte was received and stored in outbyte
\arg -1: An error occured in the transmission \arg -1: An error occured in the transmission
He must be called with at least 80 bytes of buffer. */ This must be called with at least 80 bytes of buffer. */
int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte); int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte);
int fskmodem_init(fsk_data *fskd);
#endif /* _ASTERISK_FSKMODEM_H */ #endif /* _ASTERISK_FSKMODEM_H */

View File

@@ -134,17 +134,23 @@ struct callerid_state *callerid_new(int cid_signalling)
struct callerid_state *cid; struct callerid_state *cid;
if ((cid = ast_calloc(1, sizeof(*cid)))) { if ((cid = ast_calloc(1, sizeof(*cid)))) {
cid->fskd.spb = 7.0; /* 1200 baud */ cid->fskd.ispb = 7; /* 1200 baud */
/* Set up for 1200 / 8000 freq *32 to allow ints */
cid->fskd.pllispb = (int)(8000 * 32 / 1200);
cid->fskd.pllids = cid->fskd.pllispb/32;
cid->fskd.pllispb2 = cid->fskd.pllispb/2;
cid->fskd.icont = 0; /* PLL REset */
/* cid->fskd.hdlc = 0; */ /* Async */ /* cid->fskd.hdlc = 0; */ /* Async */
cid->fskd.nbit = 8; /* 8 bits */ cid->fskd.nbit = 8; /* 8 bits */
cid->fskd.nstop = 1.0; /* 1 stop bit */ cid->fskd.instop = 1; /* 1 stop bit */
/* cid->fskd.paridad = 0; */ /* No parity */ /* cid->fskd.paridad = 0; */ /* No parity */
cid->fskd.bw = 1; /* Filter 800 Hz */ cid->fskd.bw = 1; /* Filter 800 Hz */
if (cid_signalling == 2) { /* v23 signalling */ if (cid_signalling == 2) { /* v23 signalling */
cid->fskd.f_mark_idx = 4; /* 1300 Hz */ cid->fskd.f_mark_idx = 4; /* 1300 Hz */
cid->fskd.f_space_idx = 5; /* 2100 Hz */ cid->fskd.f_space_idx = 5; /* 2100 Hz */
} else { /* Bell 202 signalling as default */ } else { /* Bell 202 signalling as default */
cid->fskd.f_mark_idx = 2; /* 1200 Hz */ cid->fskd.f_mark_idx = 2; /* 1200 Hz */
cid->fskd.f_space_idx = 3; /* 2200 Hz */ cid->fskd.f_space_idx = 3; /* 2200 Hz */
} }
/* cid->fskd.pcola = 0; */ /* No clue */ /* cid->fskd.pcola = 0; */ /* No clue */
@@ -153,6 +159,8 @@ struct callerid_state *callerid_new(int cid_signalling)
/* cid->fskd.state = 0; */ /* cid->fskd.state = 0; */
cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER; cid->flags = CID_UNKNOWN_NAME | CID_UNKNOWN_NUMBER;
/* cid->pos = 0; */ /* cid->pos = 0; */
fskmodem_init(&cid->fskd);
} }
return cid; return cid;

View File

@@ -46,17 +46,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define STATE_SEARCH_STARTBIT3 2 #define STATE_SEARCH_STARTBIT3 2
#define STATE_GET_BYTE 3 #define STATE_GET_BYTE 3
static inline float get_sample(short **buffer, int *len) static inline int iget_sample(short **buffer, int *len)
{ {
float retval; int retval;
retval = (float) **buffer / 256; retval = (int) **buffer;
(*buffer)++; (*buffer)++;
(*len)--; (*len)--;
return retval; return retval;
}; }
#define GET_SAMPLE get_sample(&buffer, len)
#define IGET_SAMPLE iget_sample(&buffer, len)
/*! \brief Coefficients for input filters /*! \brief Coefficients for input filters
* Coefficients table, generated by program "mkfilter" * Coefficients table, generated by program "mkfilter"
* mkfilter is part of the zapatatelephony.org distribution * mkfilter is part of the zapatatelephony.org distribution
@@ -64,31 +63,20 @@ static inline float get_sample(short **buffer, int *len)
* IDX_COEF = 0 => 1/GAIN * IDX_COEF = 0 => 1/GAIN
* IDX_COEF = 1-6 => Coefficientes y[n] * IDX_COEF = 1-6 => Coefficientes y[n]
*/ */
static double coef_in[NF][NBW][8] = { static double coef_in[NF][NBW][8]={
{ { { 1.8229206611e-04,-7.8997325866e-01,2.2401819940e+00,-4.6751353581e+00,5.5080745712e+00,-5.0571565772e+00,2.6215820004e+00,0.0000000000e+00,
{ 1.8229206611e-04,-7.8997325866e-01,2.2401819940e+00,-4.6751353581e+00,5.5080745712e+00,-5.0571565772e+00,2.6215820004e+00,0.0000000000e+00, }, }, { 9.8532175289e-02,-5.6297236492e-02,3.3146713415e-01,-9.2239200436e-01,1.4844365184e+00,-2.0183258642e+00,2.0074154497e+00,0.0000000000e+00,
{ 9.8532175289e-02,-5.6297236492e-02,3.3146713415e-01,-9.2239200436e-01,1.4844365184e+00,-2.0183258642e+00,2.0074154497e+00,0.0000000000e+00, }, }, }, { { 1.8229206610e-04,-7.8997325866e-01,7.7191410839e-01,-2.8075643964e+00,1.6948618347e+00,-3.0367273700e+00,9.0333559408e-01,0.0000000000e+00,
}, }, { 9.8531161839e-02,-5.6297236492e-02,1.1421579050e-01,-4.8122536483e-01,4.0121072432e-01,-7.4834487567e-01,6.9170822332e-01,0.0000000000e+00,
{ }, }, { { 1.8229206611e-04,-7.8997325866e-01,2.9003821430e+00,-6.1082779024e+00,7.7169345751e+00,-6.6075999680e+00,3.3941838836e+00,0.0000000000e+00,
{ 1.8229206610e-04,-7.8997325866e-01,7.7191410839e-01,-2.8075643964e+00,1.6948618347e+00,-3.0367273700e+00,9.0333559408e-01,0.0000000000e+00, } , }, { 9.8539686961e-02,-5.6297236492e-02,4.2915323820e-01,-1.2609358633e+00,2.2399213250e+00,-2.9928879142e+00,2.5990173742e+00,0.0000000000e+00,
{ 9.8531161839e-02,-5.6297236492e-02,1.1421579050e-01,-4.8122536483e-01,4.0121072432e-01,-7.4834487567e-01,6.9170822332e-01,0.0000000000e+00, }, }, }, { { 1.8229206610e-04,-7.8997325866e-01,-7.7191410839e-01,-2.8075643964e+00,-1.6948618347e+00,-3.0367273700e+00,-9.0333559408e-01,0.0000000000e+00,
}, }, { 9.8531161839e-02,-5.6297236492e-02,-1.1421579050e-01,-4.8122536483e-01,-4.0121072432e-01,-7.4834487567e-01,-6.9170822332e-01,0.0000000000e+00,
{ }, }, { { 1.8229206611e-04,-7.8997325866e-01,2.5782298908e+00,-5.3629717478e+00,6.5890882172e+00,-5.8012914776e+00,3.0171839130e+00,0.0000000000e+00,
{ 1.8229206611e-04,-7.8997325866e-01,2.9003821430e+00,-6.1082779024e+00,7.7169345751e+00,-6.6075999680e+00,3.3941838836e+00,0.0000000000e+00, }, }, { 9.8534230718e-02,-5.6297236492e-02,3.8148618075e-01,-1.0848760410e+00,1.8441165168e+00,-2.4860666655e+00,2.3103384142e+00,0.0000000000e+00,
{ 9.8539686961e-02,-5.6297236492e-02,4.2915323820e-01,-1.2609358633e+00,2.2399213250e+00,-2.9928879142e+00,2.5990173742e+00,0.0000000000e+00, }, }, }, { { 1.8229206610e-04,-7.8997325866e-01,-3.8715051001e-01,-2.6192408538e+00,-8.3977994034e-01,-2.8329897913e+00,-4.5306444352e-01,0.0000000000e+00,
}, }, { 9.8531160936e-02,-5.6297236492e-02,-5.7284484199e-02,-4.3673866734e-01,-1.9564766257e-01,-6.2028156584e-01,-3.4692356122e-01,0.0000000000e+00,
{ }, },
{ 1.8229206610e-04,-7.8997325866e-01,-7.7191410839e-01,-2.8075643964e+00,-1.6948618347e+00,-3.0367273700e+00,-9.0333559408e-01,0.0000000000e+00, },
{ 9.8531161839e-02,-5.6297236492e-02,-1.1421579050e-01,-4.8122536483e-01,-4.0121072432e-01,-7.4834487567e-01,-6.9170822332e-01,0.0000000000e+00, },
},
{
{ 1.8229206611e-04,-7.8997325866e-01,2.5782298908e+00,-5.3629717478e+00,6.5890882172e+00,-5.8012914776e+00,3.0171839130e+00,0.0000000000e+00, },
{ 9.8534230718e-02,-5.6297236492e-02,3.8148618075e-01,-1.0848760410e+00,1.8441165168e+00,-2.4860666655e+00,2.3103384142e+00,0.0000000000e+00, },
},
{
{ 1.8229206610e-04,-7.8997325866e-01,-3.8715051001e-01,-2.6192408538e+00,-8.3977994034e-01,-2.8329897913e+00,-4.5306444352e-01,0.0000000000e+00, },
{ 9.8531160936e-02,-5.6297236492e-02,-5.7284484199e-02,-4.3673866734e-01,-1.9564766257e-01,-6.2028156584e-01,-3.4692356122e-01,0.0000000000e+00, },
},
}; };
/*! \brief Coefficients for output filter /*! \brief Coefficients for output filter
@@ -96,134 +84,144 @@ static double coef_in[NF][NBW][8] = {
* Format: coef[IDX_BW][IDX_COEF] * Format: coef[IDX_BW][IDX_COEF]
* IDX_COEF = 0 => 1/GAIN * IDX_COEF = 0 => 1/GAIN
* IDX_COEF = 1-6 => Coefficientes y[n] * IDX_COEF = 1-6 => Coefficientes y[n]
*/ */
static double coef_out[NBW][8] = { static double coef_out[NBW][8]={
{ 1.3868644653e-08,-6.3283665042e-01,4.0895057217e+00,-1.1020074592e+01,1.5850766191e+01,-1.2835109292e+01,5.5477477340e+00,0.0000000000e+00, }, { 1.3868644653e-08,-6.3283665042e-01,4.0895057217e+00,-1.1020074592e+01,1.5850766191e+01,-1.2835109292e+01,5.5477477340e+00,0.0000000000e+00,
{ 3.1262119724e-03,-7.8390522307e-03,8.5209627801e-02,-4.0804129163e-01,1.1157139955e+00,-1.8767603680e+00,1.8916395224e+00,0.0000000000e+00, }, }, { 3.1262119724e-03,-7.8390522307e-03,8.5209627801e-02,-4.0804129163e-01,1.1157139955e+00,-1.8767603680e+00,1.8916395224e+00,0.0000000000e+00
},
}; };
/*! Integer Pass Band demodulator filter */
/*! Band-pass filter for MARK frequency */ static inline int ibpdfilter(struct filter_struct * fs, int in)
static inline float filterM(fsk_data *fskd,float in)
{ {
int i, j; int i,j;
double s; int s;
double *pc; int64_t s_interim;
pc = &coef_in[fskd->f_mark_idx][fskd->bw][0]; /* integer filter */
fskd->fmxv[(fskd->fmp+6)&7] = in*(*pc++); s = in * fs->icoefs[0];
fs->ixv[(fs->ip+6)&7] = s;
s = (fskd->fmxv[(fskd->fmp + 6) & 7] - fskd->fmxv[fskd->fmp]) + 3 * (fskd->fmxv[(fskd->fmp + 2) & 7] - fskd->fmxv[(fskd->fmp + 4) & 7]); s= (fs->ixv[fs->ip] + fs->ixv[(fs->ip+6)&7]) +
for (i = 0, j = fskd->fmp; i < 6; i++, j++) 6 * (fs->ixv[(fs->ip+1)&7] + fs->ixv[(fs->ip+5)&7]) +
s += fskd->fmyv[j&7]*(*pc++); 15 * (fs->ixv[(fs->ip+2)&7] + fs->ixv[(fs->ip+4)&7]) +
fskd->fmyv[j&7] = s; 20 * fs->ixv[(fs->ip+3)&7];
fskd->fmp++;
fskd->fmp &= 7; for (i=1,j=fs->ip; i < 7; i++,j++) {
/* Promote operation to 64 bit to prevent overflow that occurred in 32 bit) */
s_interim = (int64_t)(fs->iyv[j & 7]) *
(int64_t)(fs->icoefs[i]) /
(int64_t)(1024);
s += (int)s_interim;
}
fs->iyv[ j & 7] = s;
fs->ip++;
fs->ip &= 7;
return s; return s;
} }
/*! Band-pass filter for SPACE frequency */ /*! Integer Band Pass filter */
static inline float filterS(fsk_data *fskd,float in) static inline int ibpfilter(struct filter_struct * fs, int in)
{ {
int i, j; int i,j;
double s; int s;
double *pc; int64_t s_interim;
pc = &coef_in[fskd->f_space_idx][fskd->bw][0]; /* integer filter */
fskd->fsxv[(fskd->fsp+6)&7] = in*(*pc++); s = in * fs->icoefs[0] / 256;
fs->ixv[(fs->ip+6) & 7] = s;
s = (fskd->fsxv[(fskd->fsp + 6) & 7] - fskd->fsxv[fskd->fsp]) + 3 * (fskd->fsxv[(fskd->fsp + 2) & 7] - fskd->fsxv[(fskd->fsp + 4) & 7]); s = (fs->ixv[(fs->ip+6) & 7] - fs->ixv[fs->ip])
for (i = 0, j = fskd->fsp; i < 6; i++, j++) + 3 * (fs->ixv[(fs->ip+2) & 7] - fs->ixv[(fs->ip+4) & 7]);
s += fskd->fsyv[j&7]*(*pc++);
fskd->fsyv[j&7] = s; for (i=1,j=fs->ip; i < 7; i++,j++) {
fskd->fsp++; s_interim = (int64_t)(fs->iyv[j&7]) *
fskd->fsp &= 7; (int64_t)(fs->icoefs[i]) /
(int64_t)(256);
s+= (int)s_interim;
}
fs->iyv[j&7]=s;
fs->ip++; fs->ip &= 7;
return s; return s;
} }
/*! Low-pass filter for demodulated data */ static inline int idemodulator(fsk_data *fskd, int *retval, int x)
static inline float filterL(fsk_data *fskd,float in)
{ {
int i, j; int is, im, id;
double s; int ilin2;
double *pc;
is = ibpfilter(&fskd->space_filter, x);
im = ibpfilter(&fskd->mark_filter, x);
pc = &coef_out[fskd->bw][0]; ilin2 = ((im * im) - (is * is))/(256 * 256);
fskd->flxv[(fskd->flp + 6) & 7] = in * (*pc++);
s = (fskd->flxv[fskd->flp] + fskd->flxv[(fskd->flp+6)&7]) + id = ibpdfilter(&fskd->demod_filter, ilin2);
6 * (fskd->flxv[(fskd->flp+1)&7] + fskd->flxv[(fskd->flp+5)&7]) +
15 * (fskd->flxv[(fskd->flp+2)&7] + fskd->flxv[(fskd->flp+4)&7]) +
20 * fskd->flxv[(fskd->flp+3)&7];
for (i = 0,j = fskd->flp;i<6;i++,j++) *retval = id;
s += fskd->flyv[j&7]*(*pc++);
fskd->flyv[j&7] = s;
fskd->flp++;
fskd->flp &= 7;
return s;
}
static inline int demodulator(fsk_data *fskd, float *retval, float x)
{
float xS,xM;
fskd->cola_in[fskd->pcola] = x;
xS = filterS(fskd,x);
xM = filterM(fskd,x);
fskd->cola_filter[fskd->pcola] = xM-xS;
x = filterL(fskd,xM*xM - xS*xS);
fskd->cola_demod[fskd->pcola++] = x;
fskd->pcola &= (NCOLA-1);
*retval = x;
return 0; return 0;
} }
static int get_bit_raw(fsk_data *fskd, short *buffer, int *len) static int get_bit_raw(fsk_data *fskd, short *buffer, int *len)
{ {
/* This function implements a DPLL to synchronize with the bits */ /* This function implements a DPLL to synchronize with the bits */
float x,spb,spb2,ds;
int f; int f;
spb = fskd->spb; int ix;
if (fskd->spb == 7) /* PLL coeffs are set up in callerid_new */
spb = 8000.0 / 1200.0; for (f = 0;;){
ds = spb/32.; if (idemodulator(fskd, &ix, IGET_SAMPLE)) return(-1);
spb2 = spb/2.; if ((ix * fskd->xi0)<0) { /* Transicion */
for (f = 0;;) {
if (demodulator(fskd, &x, GET_SAMPLE))
return -1;
if ((x * fskd->x0) < 0) { /* Transition */
if (!f) { if (!f) {
if (fskd->cont<(spb2)) if (fskd->icont<(fskd->pllispb2))
fskd->cont += ds; fskd->icont+=fskd->pllids;
else else
fskd->cont -= ds; fskd->icont-=fskd->pllids;
f = 1; f=1;
} }
} }
fskd->x0 = x; fskd->xi0=ix;
fskd->cont += 1.; fskd->icont+=32;
if (fskd->cont > spb) { if (fskd->icont>fskd->pllispb) {
fskd->cont -= spb; fskd->icont-=fskd->pllispb;
break; break;
} }
} }
f = (x > 0) ? 0x80 : 0; f=(ix>0)?0x80:0;
return f; return f;
} }
int fskmodem_init(fsk_data *fskd)
{
int i;
fskd->space_filter.ip = 0;
fskd->mark_filter.ip = 0;
fskd->demod_filter.ip = 0;
for ( i = 0 ; i < 7 ; i++ ) {
fskd->space_filter.icoefs[i] =
coef_in[fskd->f_space_idx][fskd->bw][i] * 256;
fskd->space_filter.ixv[i] = 0;;
fskd->space_filter.iyv[i] = 0;;
fskd->mark_filter.icoefs[i] =
coef_in[fskd->f_mark_idx][fskd->bw][i] * 256;
fskd->mark_filter.ixv[i] = 0;;
fskd->mark_filter.iyv[i] = 0;;
fskd->demod_filter.icoefs[i] =
coef_out[fskd->bw][i] * 1024;
fskd->demod_filter.ixv[i] = 0;;
fskd->demod_filter.iyv[i] = 0;;
}
return 0;
}
int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte) int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte)
{ {
int a; int a;
int i,j,n1,r; int i,j,n1,r;
int samples = 0; int samples=0;
int olen; int olen;
int beginlen=*len; int beginlen=*len;
int beginlenx; int beginlenx;
@@ -243,56 +241,58 @@ int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte)
to look for the beginning of the start bit. Unfortunately, since TTY/TDD's to look for the beginning of the start bit. Unfortunately, since TTY/TDD's
just start sending a start bit with nothing preceding it at the beginning just start sending a start bit with nothing preceding it at the beginning
of a transmission (what a LOSING design), we cant do it this elegantly */ of a transmission (what a LOSING design), we cant do it this elegantly */
/* /* NOT USED
if (demodulator(zap,&x1)) return(-1); if (demodulator(zap,&x1))
for (;;) { return -1;
if (demodulator(zap,&x2)) return(-1); for(;;) {
if (x1>0 && x2<0) break; if (demodulator(zap,&x2))
x1 = x2; return -1;
} if (x1>0 && x2<0) break;
x1=x2;
}
*/ */
/* this is now the imprecise, losing, but functional code to detect the /* this is now the imprecise, losing, but functional code to detect the
beginning of a start bit in the TDD sceanario. It just looks for sufficient beginning of a start bit in the TDD sceanario. It just looks for sufficient
level to maybe, perhaps, guess, maybe that its maybe the beginning of level to maybe, perhaps, guess, maybe that its maybe the beginning of
a start bit, perhaps. This whole thing stinks! */ a start bit, perhaps. This whole thing stinks! */
beginlenx=beginlen; /* just to avoid unused war warnings */ beginlenx=beginlen; /* just to avoid unused war warnings */
if (demodulator(fskd, &fskd->x1, GET_SAMPLE)) if (idemodulator(fskd, &fskd->xi1, IGET_SAMPLE))
return -1; return -1;
samples++; samples++;
for (;;) { for(;;) {
search_startbit2: search_startbit2:
if (*len <= 0) { if (*len <= 0) {
fskd->state = STATE_SEARCH_STARTBIT2; fskd->state = STATE_SEARCH_STARTBIT2;
return 0; return 0;
} }
samples++; samples++;
if (demodulator(fskd, &fskd->x2, GET_SAMPLE)) if (idemodulator(fskd,&fskd->xi2,IGET_SAMPLE))
return(-1); return -1;
#if 0 #if 0
printf("x2 = %5.5f ", fskd->x2); printf("xi2 = %d ", fskd->xi2);
#endif #endif
if (fskd->x2 < -0.5) if (fskd->xi2 < 512)
break; break;
} }
search_startbit3: search_startbit3:
/* We await for 0.5 bits before using DPLL */ /* We await for 0.5 bits before using DPLL */
i = fskd->spb/2; i=fskd->ispb/2;
if (*len < i) { if (*len < i) {
fskd->state = STATE_SEARCH_STARTBIT3; fskd->state = STATE_SEARCH_STARTBIT3;
return 0; return 0;
} }
for (; i>0; i--) { for (; i>0; i--) {
if (demodulator(fskd, &fskd->x1, GET_SAMPLE)) if (idemodulator(fskd, &fskd->xi1, IGET_SAMPLE))
return(-1); return(-1);
#if 0 #if 0
printf("x1 = %5.5f ", fskd->x1); printf("xi1 = %d ", fskd->xi1);
#endif #endif
samples++; samples++;
} }
/* x1 must be negative (start bit confirmation) */ /* x1 must be negative (start bit confirmation) */
} while (fskd->x1 > 0); } while (fskd->xi1>0);
fskd->state = STATE_GET_BYTE; fskd->state = STATE_GET_BYTE;
getbyte: getbyte:
@@ -306,18 +306,19 @@ getbyte:
if (*len < 80) if (*len < 80)
return 0; return 0;
} }
/* Now we read the data bits */ /* Now we read the data bits */
j = fskd->nbit; j = fskd->nbit;
for (a = n1 = 0; j; j--) { for (a = n1 = 0; j; j--) {
olen = *len; olen = *len;
i = get_bit_raw(fskd, buffer, len); i = get_bit_raw(fskd, buffer, len);
buffer += (olen - *len); buffer += (olen - *len);
if (i == -1) if (i == -1)
return(-1); return -1;
if (i) if (i)
n1++; n1++;
a >>= 1; a >>= 1;
a |= i; a |= i;
} }
j = 8-fskd->nbit; j = 8-fskd->nbit;
a >>= j; a >>= j;
@@ -327,33 +328,34 @@ getbyte:
olen = *len; olen = *len;
i = get_bit_raw(fskd, buffer, len); i = get_bit_raw(fskd, buffer, len);
buffer += (olen - *len); buffer += (olen - *len);
if (i == -1) if (i == -1)
return(-1); return -1;
if (i) if (i)
n1++; n1++;
if (fskd->parity == 1) { /* parity=1 (even) */ if (fskd->parity == 1) { /* parity=1 (even) */
if (n1&1) if (n1&1)
a |= 0x100; /* error */ a |= 0x100; /* error */
} else { /* parity=2 (odd) */ } else { /* parity=2 (odd) */
if (!(n1&1)) if (!(n1&1))
a |= 0x100; /* error */ a |= 0x100; /* error */
} }
} }
/* We read STOP bits. All of them must be 1 */ /* We read STOP bits. All of them must be 1 */
for (j = fskd->nstop;j;j--) { for (j=fskd->instop; j; j--) {
r = get_bit_raw(fskd, buffer, len); r = get_bit_raw(fskd, buffer, len);
if (r == -1) if (r == -1)
return(-1); return -1;
if (!r) if (!r)
a |= 0x200; a |= 0x200;
} }
/* And finally we return */ /* And finally we return
/* Bit 8 : Parity error */ * Bit 8 : Parity error
/* Bit 9 : Framming error*/ * Bit 9 : Framming error
*/
*outbyte = a; *outbyte = a;
fskd->state = STATE_SEARCH_STARTBIT; fskd->state = STATE_SEARCH_STARTBIT;
return 1; return 1;

View File

@@ -103,20 +103,23 @@ struct tdd_state *tdd_new(void)
struct tdd_state *tdd; struct tdd_state *tdd;
tdd = calloc(1, sizeof(*tdd)); tdd = calloc(1, sizeof(*tdd));
if (tdd) { if (tdd) {
tdd->fskd.spb = 176; /* 45.5 baud */ tdd->fskd.ispb = 176; /* 45.5 baud */
/* Set up for 45.5 / 8000 freq *32 to allow ints */
tdd->fskd.pllispb = (int)((8000 * 32 * 2) / 90);
tdd->fskd.pllids = tdd->fskd.pllispb/32;
tdd->fskd.pllispb2 = tdd->fskd.pllispb/2;
tdd->fskd.hdlc = 0; /* Async */ tdd->fskd.hdlc = 0; /* Async */
tdd->fskd.nbit = 5; /* 5 bits */ tdd->fskd.nbit = 5; /* 5 bits */
tdd->fskd.nstop = 1.5; /* 1.5 stop bits */ tdd->fskd.instop = 1; /* integer rep of 1.5 stop bits */
tdd->fskd.parity = 0; /* No parity */ tdd->fskd.parity = 0; /* No parity */
tdd->fskd.bw=0; /* Filter 75 Hz */ tdd->fskd.bw=0; /* Filter 75 Hz */
tdd->fskd.f_mark_idx = 0; /* 1400 Hz */ tdd->fskd.f_mark_idx = 0; /* 1400 Hz */
tdd->fskd.f_space_idx = 1; /* 1800 Hz */ tdd->fskd.f_space_idx = 1; /* 1800 Hz */
tdd->fskd.pcola = 0; /* No clue */ tdd->fskd.xi0 = 0;
tdd->fskd.cont = 0; /* Digital PLL reset */
tdd->fskd.x0 = 0.0;
tdd->fskd.state = 0; tdd->fskd.state = 0;
tdd->pos = 0; tdd->pos = 0;
tdd->mode = 2; tdd->mode = 2;
fskmodem_init(&tdd->fskd);
} else } else
ast_log(LOG_WARNING, "Out of memory\n"); ast_log(LOG_WARNING, "Out of memory\n");
return tdd; return tdd;