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

FSK Modulator/Demodulator. More...

#include "asterisk.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 IGET_SAMPLE   iget_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

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...
 
int fskmodem_init (fsk_data *fskd)
 
static int get_bit_raw (fsk_data *fskd, short *buffer, int *len)
 
static int ibpdfilter (struct filter_struct *fs, int in)
 
static int ibpfilter (struct filter_struct *fs, int in)
 
static int idemodulator (fsk_data *fskd, int *retval, int x)
 
static int iget_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_int.c.

Function Documentation

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 222 of file fskmodem_int.c.

References fsk_data::instop, fsk_data::nbit, and fsk_data::parity.

Referenced by callerid_feed(), callerid_feed_jp(), and tdd_feed().

223 {
224  int a;
225  int i, j, n1, r;
226  int samples = 0;
227  int olen;
228  int beginlen = *len;
229  int beginlenx;
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  /* NOT USED
247  if (demodulator(zap,&x1))
248  return -1;
249  for(;;) {
250  if (demodulator(zap,&x2))
251  return -1;
252  if (x1>0 && x2<0) break;
253  x1=x2;
254  }
255  */
256  /* this is now the imprecise, losing, but functional code to detect the
257  beginning of a start bit in the TDD sceanario. It just looks for sufficient
258  level to maybe, perhaps, guess, maybe that its maybe the beginning of
259  a start bit, perhaps. This whole thing stinks! */
260  beginlenx = beginlen; /* just to avoid unused war warnings */
261  if (idemodulator(fskd, &fskd->xi1, IGET_SAMPLE))
262  return -1;
263  samples++;
264  for(;;) {
265 search_startbit2:
266  if (*len <= 0) {
267  fskd->state = STATE_SEARCH_STARTBIT2;
268  return 0;
269  }
270  samples++;
271  if (idemodulator(fskd, &fskd->xi2, IGET_SAMPLE))
272  return -1;
273 #if 0
274  printf("xi2 = %d ", fskd->xi2);
275 #endif
276  if (fskd->xi2 < 512) {
277  break;
278  }
279  }
280 search_startbit3:
281  /* We await for 0.5 bits before using DPLL */
282  i = fskd->ispb / 2;
283  if (*len < i) {
284  fskd->state = STATE_SEARCH_STARTBIT3;
285  return 0;
286  }
287  for (; i > 0; i--) {
288  if (idemodulator(fskd, &fskd->xi1, IGET_SAMPLE))
289  return(-1);
290 #if 0
291  printf("xi1 = %d ", fskd->xi1);
292 #endif
293  samples++;
294  }
295 
296  /* x1 must be negative (start bit confirmation) */
297 
298  } while (fskd->xi1 > 0);
299  fskd->state = STATE_GET_BYTE;
300 
301 getbyte:
302 
303  /* Need at least 80 samples (for 1200) or
304  1320 (for 45.5) to be sure we'll have a byte */
305  if (fskd->nbit < 8) {
306  if (*len < 1320)
307  return 0;
308  } else {
309  if (*len < 80)
310  return 0;
311  }
312 
313  /* Now we read the data bits */
314  j = fskd->nbit;
315  for (a = n1 = 0; j; j--) {
316  olen = *len;
317  i = get_bit_raw(fskd, buffer, len);
318  buffer += (olen - *len);
319  if (i == -1)
320  return -1;
321  if (i)
322  n1++;
323  a >>= 1;
324  a |= i;
325  }
326  j = 8 - fskd->nbit;
327  a >>= j;
328 
329  /* We read parity bit (if exists) and check parity */
330  if (fskd->parity) {
331  olen = *len;
332  i = get_bit_raw(fskd, buffer, len);
333  buffer += (olen - *len);
334  if (i == -1)
335  return -1;
336  if (i)
337  n1++;
338  if (fskd->parity == 1) { /* parity=1 (even) */
339  if (n1 & 1)
340  a |= 0x100; /* error */
341  } else { /* parity=2 (odd) */
342  if (!(n1 & 1))
343  a |= 0x100; /* error */
344  }
345  }
346 
347  /* We read STOP bits. All of them must be 1 */
348 
349  for (j = fskd->instop; j; j--) {
350  r = get_bit_raw(fskd, buffer, len);
351  if (r == -1)
352  return -1;
353  if (!r)
354  a |= 0x200;
355  }
356 
357  /* And finally we return
358  * Bit 8 : Parity error
359  * Bit 9 : Framing error
360  */
361 
362  *outbyte = a;
363  fskd->state = STATE_SEARCH_STARTBIT;
364  return 1;
365 }
int instop
Definition: fskmodem_int.h:46
static int ibpdfilter ( struct filter_struct fs,
int  in 
)
inlinestatic

Integer Pass Band demodulator filter

Definition at line 95 of file fskmodem_int.c.

96 {
97  int i,j;
98  int s;
99  int64_t s_interim;
100 
101  /* integer filter */
102  s = in * fs->icoefs[0];
103  fs->ixv[(fs->ip + 6) & 7] = s;
104 
105  s = (fs->ixv[fs->ip] + fs->ixv[(fs->ip + 6) & 7]) +
106  6 * (fs->ixv[(fs->ip + 1) & 7] + fs->ixv[(fs->ip + 5) & 7]) +
107  15 * (fs->ixv[(fs->ip + 2) & 7] + fs->ixv[(fs->ip + 4) & 7]) +
108  20 * fs->ixv[(fs->ip + 3) & 7];
109 
110  for (i = 1, j = fs->ip; i < 7; i++, j++) {
111  /* Promote operation to 64 bit to prevent overflow that occurred in 32 bit) */
112  s_interim = (int64_t)(fs->iyv[j & 7]) *
113  (int64_t)(fs->icoefs[i]) /
114  (int64_t)(1024);
115  s += (int) s_interim;
116  }
117  fs->iyv[j & 7] = s;
118  fs->ip++;
119  fs->ip &= 7;
120  return s;
121 }
static int ibpfilter ( struct filter_struct fs,
int  in 
)
inlinestatic

Integer Band Pass filter

Definition at line 124 of file fskmodem_int.c.

125 {
126  int i, j;
127  int s;
128  int64_t s_interim;
129 
130  /* integer filter */
131  s = in * fs->icoefs[0] / 256;
132  fs->ixv[(fs->ip + 6) & 7] = s;
133 
134  s = (fs->ixv[(fs->ip + 6) & 7] - fs->ixv[fs->ip])
135  + 3 * (fs->ixv[(fs->ip + 2) & 7] - fs->ixv[(fs->ip + 4) & 7]);
136 
137  for (i = 1, j = fs->ip; i < 7; i++, j++) {
138  s_interim = (int64_t)(fs->iyv[j & 7]) *
139  (int64_t)(fs->icoefs[i]) /
140  (int64_t)(256);
141  s += (int) s_interim;
142  }
143  fs->iyv[j & 7] = s;
144  fs->ip++;
145  fs->ip &= 7;
146  return s;
147 }

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 88 of file fskmodem_int.c.