Asterisk - The Open Source Telephony Project  21.4.1
Macros | Functions | Variables
fskmodem_float.c File Reference

FSK Modulator/Demodulator. More...

#include "asterisk.h"
#include <stdio.h>
#include "asterisk/fskmodem.h"

Go to the source code of this file.

Macros

#define BWLIST   {75,800}
 
#define FLIST   {1400,1800,1200,2200,1300,2100}
 
#define GET_SAMPLE   get_sample(&buffer, len)
 
#define NBW   2
 
#define NF   6
 
#define STATE_GET_BYTE   3
 
#define STATE_SEARCH_STARTBIT   0
 
#define STATE_SEARCH_STARTBIT2   1
 
#define STATE_SEARCH_STARTBIT3   2
 

Functions

static int demodulator (fsk_data *fskd, float *retval, float x)
 
static float filterL (fsk_data *fskd, float in)
 
static float filterM (fsk_data *fskd, float in)
 
static float filterS (fsk_data *fskd, float in)
 
int fsk_serial (fsk_data *fskd, short *buffer, int *len, int *outbyte)
 Retrieve a serial byte into outbyte. Buffer is a pointer into a series of shorts and len records the number of bytes in the buffer. len will be overwritten with the number of bytes left that were not consumed. More...
 
static int get_bit_raw (fsk_data *fskd, short *buffer, int *len)
 
static float get_sample (short **buffer, int *len)
 

Variables

static double coef_in [NF][NBW][8]
 Coefficients for input filters Coefficients table, generated by program "mkfilter" mkfilter is part of the zapatatelephony.org distribution Format: coef[IDX_FREC][IDX_BW][IDX_COEF] IDX_COEF = 0 => 1/GAIN IDX_COEF = 1-6 => Coefficientes y[n].
 
static double coef_out [NBW][8]
 Coefficients for output filter Coefficients table, generated by program "mkfilter" Format: coef[IDX_BW][IDX_COEF] IDX_COEF = 0 => 1/GAIN IDX_COEF = 1-6 => Coefficientes y[n]. More...
 

Detailed Description

FSK Modulator/Demodulator.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file fskmodem_float.c.

Function Documentation

static float filterL ( fsk_data fskd,
float  in 
)
inlinestatic

Low-pass filter for demodulated data

Definition at line 147 of file fskmodem_float.c.

References fsk_data::bw, coef_out, fsk_data::flp, and fsk_data::flyv.

148 {
149  int i, j;
150  double s;
151  double *pc;
152 
153  pc = &coef_out[fskd->bw][0];
154  fskd->flxv[(fskd->flp + 6) & 7] = in * (*pc++);
155 
156  s = (fskd->flxv[fskd->flp] + fskd->flxv[(fskd->flp+6)&7]) +
157  6 * (fskd->flxv[(fskd->flp+1)&7] + fskd->flxv[(fskd->flp+5)&7]) +
158  15 * (fskd->flxv[(fskd->flp+2)&7] + fskd->flxv[(fskd->flp+4)&7]) +
159  20 * fskd->flxv[(fskd->flp+3)&7];
160 
161  for (i = 0,j = fskd->flp;i<6;i++,j++)
162  s += fskd->flyv[j&7]*(*pc++);
163  fskd->flyv[j&7] = s;
164  fskd->flp++;
165  fskd->flp &= 7;
166  return s;
167 }
static double coef_out[NBW][8]
Coefficients for output filter Coefficients table, generated by program "mkfilter" Format: coef[IDX_B...
double flyv[8]
static float filterM ( fsk_data fskd,
float  in 
)
inlinestatic

Band-pass filter for MARK frequency

Definition at line 109 of file fskmodem_float.c.

References fsk_data::bw, coef_in, fsk_data::f_mark_idx, fsk_data::fmp, and fsk_data::fmyv.

110 {
111  int i, j;
112  double s;
113  double *pc;
114 
115  pc = &coef_in[fskd->f_mark_idx][fskd->bw][0];
116  fskd->fmxv[(fskd->fmp+6)&7] = in*(*pc++);
117 
118  s = (fskd->fmxv[(fskd->fmp + 6) & 7] - fskd->fmxv[fskd->fmp]) + 3 * (fskd->fmxv[(fskd->fmp + 2) & 7] - fskd->fmxv[(fskd->fmp + 4) & 7]);
119  for (i = 0, j = fskd->fmp; i < 6; i++, j++)
120  s += fskd->fmyv[j&7]*(*pc++);
121  fskd->fmyv[j&7] = s;
122  fskd->fmp++;
123  fskd->fmp &= 7;
124  return s;
125 }
double fmyv[8]
static double coef_in[NF][NBW][8]
Coefficients for input filters Coefficients table, generated by program "mkfilter" mkfilter is part o...
int f_mark_idx
static float filterS ( fsk_data fskd,
float  in 
)
inlinestatic

Band-pass filter for SPACE frequency

Definition at line 128 of file fskmodem_float.c.

References fsk_data::bw, coef_in, fsk_data::f_space_idx, fsk_data::fsp, and fsk_data::fsyv.

129 {
130  int i, j;
131  double s;
132  double *pc;
133 
134  pc = &coef_in[fskd->f_space_idx][fskd->bw][0];
135  fskd->fsxv[(fskd->fsp+6)&7] = in*(*pc++);
136 
137  s = (fskd->fsxv[(fskd->fsp + 6) & 7] - fskd->fsxv[fskd->fsp]) + 3 * (fskd->fsxv[(fskd->fsp + 2) & 7] - fskd->fsxv[(fskd->fsp + 4) & 7]);
138  for (i = 0, j = fskd->fsp; i < 6; i++, j++)
139  s += fskd->fsyv[j&7]*(*pc++);
140  fskd->fsyv[j&7] = s;
141  fskd->fsp++;
142  fskd->fsp &= 7;
143  return s;
144 }
double fsyv[8]
static double coef_in[NF][NBW][8]
Coefficients for input filters Coefficients table, generated by program "mkfilter" mkfilter is part o...
int f_space_idx
int fsk_serial ( fsk_data fskd,
short *  buffer,
int *  len,
int *  outbyte 
)

Retrieve a serial byte into outbyte. Buffer is a pointer into a series of shorts and len records the number of bytes in the buffer. len will be overwritten with the number of bytes left that were not consumed.

Return values
0Still looking for something...
1An output byte was received and stored in outbyte
-1An error occured in the transmission He must be called with at least 80 bytes of buffer.

Definition at line 224 of file fskmodem_float.c.

References ast_frame::len, fsk_data::nbit, fsk_data::nstop, fsk_data::parity, ast_frame::samples, and fsk_data::spb.

225 {
226  int a;
227  int i,j,n1,r;
228  int samples = 0;
229  int olen;
230 
231  switch (fskd->state) {
232  /* Pick up where we left off */
233  case STATE_SEARCH_STARTBIT2:
234  goto search_startbit2;
235  case STATE_SEARCH_STARTBIT3:
236  goto search_startbit3;
237  case STATE_GET_BYTE:
238  goto getbyte;
239  }
240  /* We await for start bit */
241  do {
242  /* this was jesus's nice, reasonable, working (at least with RTTY) code
243  to look for the beginning of the start bit. Unfortunately, since TTY/TDD's
244  just start sending a start bit with nothing preceding it at the beginning
245  of a transmission (what a LOSING design), we cant do it this elegantly */
246  /*
247  if (demodulator(zap,&x1)) return(-1);
248  for (;;) {
249  if (demodulator(zap,&x2)) return(-1);
250  if (x1>0 && x2<0) break;
251  x1 = x2;
252  }
253  */
254  /* this is now the imprecise, losing, but functional code to detect the
255  beginning of a start bit in the TDD sceanario. It just looks for sufficient
256  level to maybe, perhaps, guess, maybe that its maybe the beginning of
257  a start bit, perhaps. This whole thing stinks! */
258  if (demodulator(fskd, &fskd->x1, GET_SAMPLE))
259  return -1;
260  samples++;
261  for (;;) {
262 search_startbit2:
263  if (*len <= 0) {
264  fskd->state = STATE_SEARCH_STARTBIT2;
265  return 0;
266  }
267  samples++;
268  if (demodulator(fskd, &fskd->x2, GET_SAMPLE))
269  return(-1);
270 #if 0
271  printf("x2 = %5.5f ", fskd->x2);
272 #endif
273  if (fskd->x2 < -0.5)
274  break;
275  }
276 search_startbit3:
277  /* We await for 0.5 bits before using DPLL */
278  i = fskd->spb/2;
279  if (*len < i) {
280  fskd->state = STATE_SEARCH_STARTBIT3;
281  return 0;
282  }
283  for (; i>0; i--) {
284  if (demodulator(fskd, &fskd->x1, GET_SAMPLE))
285  return(-1);
286 #if 0
287  printf("x1 = %5.5f ", fskd->x1);
288 #endif
289  samples++;
290  }
291 
292  /* x1 must be negative (start bit confirmation) */
293 
294  } while (fskd->x1 > 0);
295  fskd->state = STATE_GET_BYTE;
296 
297 getbyte:
298 
299  /* Need at least 80 samples (for 1200) or
300  1320 (for 45.5) to be sure we'll have a byte */
301  if (fskd->nbit < 8) {
302  if (*len < 1320)
303  return 0;
304  } else {
305  if (*len < 80)
306  return 0;
307  }
308  /* Now we read the data bits */
309  j = fskd->nbit;
310  for (a = n1 = 0; j; j--) {
311  olen = *len;
312  i = get_bit_raw(fskd, buffer, len);
313  buffer += (olen - *len);
314  if (i == -1)
315  return(-1);
316  if (i)
317  n1++;
318  a >>= 1;
319  a |= i;
320  }
321  j = 8-fskd->nbit;
322  a >>= j;
323 
324  /* We read parity bit (if exists) and check parity */
325  if (fskd->parity) {
326  olen = *len;
327  i = get_bit_raw(fskd, buffer, len);
328  buffer += (olen - *len);
329  if (i == -1)
330  return(-1);
331  if (i)
332  n1++;
333  if (fskd->parity == 1) { /* parity=1 (even) */
334  if (n1&1)
335  a |= 0x100; /* error */
336  } else { /* parity=2 (odd) */
337  if (!(n1&1))
338  a |= 0x100; /* error */
339  }
340  }
341 
342  /* We read STOP bits. All of them must be 1 */
343 
344  for (j = fskd->nstop;j;j--) {
345  r = get_bit_raw(fskd, buffer, len);
346  if (r == -1)
347  return(-1);
348  if (!r)
349  a |= 0x200;
350  }
351 
352  /* And finally we return */
353  /* Bit 8 : Parity error */
354  /* Bit 9 : Framing error*/
355 
356  *outbyte = a;
357  fskd->state = STATE_SEARCH_STARTBIT;
358  return 1;
359 }
float nstop

Variable Documentation

double coef_out[NBW][8]
static
Initial value:
= {
{ 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, },
}

Coefficients for output filter Coefficients table, generated by program "mkfilter" Format: coef[IDX_BW][IDX_COEF] IDX_COEF = 0 => 1/GAIN IDX_COEF = 1-6 => Coefficientes y[n].

Definition at line 102 of file fskmodem_float.c.

Referenced by filterL().