Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:55 2009

## Asterisk developer's documentation

# fskmodem.c File Reference

FSK Modulator/Demodulator. More...

`#include <stdio.h>`
`#include "asterisk.h"`
`#include "asterisk/fskmodem.h"`
`#include "coef_in.h"`
`#include "coef_out.h"`

Include dependency graph for fskmodem.c:

Go to the source code of this file.

## Defines

#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 | demodulador (fsk_data *fskd, float *retval, float x)
static float | filtroL (fsk_data *fskd, float in)
static float | filtroM (fsk_data *fskd, float in)
static float | filtroS (fsk_data *fskd, float in)
int | fsk_serie (fsk_data *fskd, short *buffer, int *len, int *outbyte)
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]
static double | coef_out [NBW][8]

## Detailed Description

FSK Modulator/Demodulator.

Definition in file fskmodem.c.

## Define Documentation

#define BWLIST {75,800}

Definition at line 36 of file fskmodem.c.

#define FLIST {1400,1800,1200,2200,1300,2100}

Definition at line 38 of file fskmodem.c.

#define GET_SAMPLE get_sample(&buffer, len)

Definition at line 54 of file fskmodem.c.

Referenced by fsk_serie(), and get_bit_raw().

#define NBW 2

Definition at line 35 of file fskmodem.c.

#define NF 6

Definition at line 37 of file fskmodem.c.

#define STATE_GET_BYTE 3

Definition at line 43 of file fskmodem.c.

Referenced by fsk_serie().

#define STATE_SEARCH_STARTBIT 0

Definition at line 40 of file fskmodem.c.

Referenced by fsk_serie().

#define STATE_SEARCH_STARTBIT2 1

Definition at line 41 of file fskmodem.c.

Referenced by fsk_serie().

#define STATE_SEARCH_STARTBIT3 2

Definition at line 42 of file fskmodem.c.

Referenced by fsk_serie().

## Function Documentation

static int demodulador | ( | fsk_data * | fskd,
|  | float * | retval,
|  | float | x |
| ) |  |  | `[inline, static]`

Definition at line 132 of file fskmodem.c.

References fsk_data::cola_demod, fsk_data::cola_filtro, fsk_data::cola_in, filtroL(), filtroM(), filtroS(), NCOLA, and fsk_data::pcola.

Referenced by fsk_serie(), and get_bit_raw().

    00133 {
    00134    float xS,xM;
    00135
    00136    fskd->cola_in[fskd->pcola]=x;
    00137
    00138    xS=filtroS(fskd,x);
    00139    xM=filtroM(fskd,x);
    00140
    00141    fskd->cola_filtro[fskd->pcola]=xM-xS;
    00142
    00143    x=filtroL(fskd,xM*xM - xS*xS);
    00144
    00145    fskd->cola_demod[fskd->pcola++]=x;
    00146    fskd->pcola &= (NCOLA-1);
    00147
    00148    *retval = x;
    00149    return(0);
    00150 }

static float filtroL | ( | fsk_data * | fskd,
|  | float | in |
| ) |  |  | `[inline, static]`

Filtro pasa-bajos para datos demodulados

Definition at line 112 of file fskmodem.c.

References fsk_data::bw, fsk_data::flp, fsk_data::flxv, fsk_data::flyv, and s.

Referenced by demodulador().

    00113 {
    00114    int i,j;
    00115    double s;
    00116    double *pc;
    00117
    00118    pc=&coef_out[fskd->bw][0];
    00119    fskd->flxv[(fskd->flp + 6) & 7]=in * (*pc++);
    00120
    00121    s=     (fskd->flxv[fskd->flp]       + fskd->flxv[(fskd->flp+6)&7]) +
    00122      6  * (fskd->flxv[(fskd->flp+1)&7] + fskd->flxv[(fskd->flp+5)&7]) +
    00123      15 * (fskd->flxv[(fskd->flp+2)&7] + fskd->flxv[(fskd->flp+4)&7]) +
    00124      20 *  fskd->flxv[(fskd->flp+3)&7];
    00125
    00126    for (i=0,j=fskd->flp;i<6;i++,j++) s+=fskd->flyv[j&7]*(*pc++);
    00127    fskd->flyv[j&7]=s;
    00128    fskd->flp++; fskd->flp&=7;
    00129    return s;
    00130 }

static float filtroM | ( | fsk_data * | fskd,
|  | float | in |
| ) |  |  | `[inline, static]`

Filtro pasa-banda para frecuencia de MARCA

Definition at line 78 of file fskmodem.c.

References fsk_data::bw, fsk_data::f_mark_idx, fsk_data::fmp, fsk_data::fmxv, fsk_data::fmyv, and s.

Referenced by demodulador().

    00079 {
    00080    int i,j;
    00081    double s;
    00082    double *pc;
    00083
    00084    pc=&coef_in[fskd->f_mark_idx][fskd->bw][0];
    00085    fskd->fmxv[(fskd->fmp+6)&7]=in*(*pc++);
    00086
    00087    s=(fskd->fmxv[(fskd->fmp+6)&7] - fskd->fmxv[fskd->fmp]) + 3 * (fskd->fmxv[(fskd->fmp+2)&7] - fskd->fmxv[(fskd->fmp+4)&7]);
    00088    for (i=0,j=fskd->fmp;i<6;i++,j++) s+=fskd->fmyv[j&7]*(*pc++);
    00089    fskd->fmyv[j&7]=s;
    00090    fskd->fmp++; fskd->fmp&=7;
    00091    return s;
    00092 }

static float filtroS | ( | fsk_data * | fskd,
|  | float | in |
| ) |  |  | `[inline, static]`

Filtro pasa-banda para frecuencia de ESPACIO

Definition at line 95 of file fskmodem.c.

References fsk_data::bw, fsk_data::f_space_idx, fsk_data::fsp, fsk_data::fsxv, fsk_data::fsyv, and s.

Referenced by demodulador().

    00096 {
    00097    int i,j;
    00098    double s;
    00099    double *pc;
    00100
    00101    pc=&coef_in[fskd->f_space_idx][fskd->bw][0];
    00102    fskd->fsxv[(fskd->fsp+6)&7]=in*(*pc++);
    00103
    00104    s=(fskd->fsxv[(fskd->fsp+6)&7] - fskd->fsxv[fskd->fsp]) + 3 * (fskd->fsxv[(fskd->fsp+2)&7] - fskd->fsxv[(fskd->fsp+4)&7]);
    00105    for (i=0,j=fskd->fsp;i<6;i++,j++) s+=fskd->fsyv[j&7]*(*pc++);
    00106    fskd->fsyv[j&7]=s;
    00107    fskd->fsp++; fskd->fsp&=7;
    00108    return s;
    00109 }

int fsk_serie | ( | fsk_data * | fskd,
|  | short * | buffer,
|  | int * | len,
|  | int * | outbyte |
| ) |  |  |

Definition at line 182 of file fskmodem.c.

References demodulador(), get_bit_raw(), GET_SAMPLE, fsk_data::nbit, fsk_data::nstop, fsk_data::paridad, ast_frame::samples, fsk_data::spb, fsk_data::state, STATE_GET_BYTE, STATE_SEARCH_STARTBIT, STATE_SEARCH_STARTBIT2, STATE_SEARCH_STARTBIT3, fsk_data::x1, and fsk_data::x2.

Referenced by callerid_feed(), and tdd_feed().

    00183 {
    00184    int a;
    00185    int i,j,n1,r;
    00186    int samples=0;
    00187    int olen;
    00188    int beginlen=*len;
    00189    int beginlenx;
    00190
    00191    switch(fskd->state) {
    00192       /* Pick up where we left off */
    00193    case STATE_SEARCH_STARTBIT2:
    00194       goto search_startbit2;
    00195    case STATE_SEARCH_STARTBIT3:
    00196       goto search_startbit3;
    00197    case STATE_GET_BYTE:
    00198       goto getbyte;
    00199    }
    00200    /* Esperamos bit de start  */
    00201    do {
    00202 /* this was jesus's nice, reasonable, working (at least with RTTY) code
    00203 to look for the beginning of the start bit. Unfortunately, since TTY/TDD's
    00204 just start sending a start bit with nothing preceding it at the beginning
    00205 of a transmission (what a LOSING design), we cant do it this elegantly */
    00206 /*
    00207       if (demodulador(zap,&x1)) return(-1);
    00208       for(;;) {
    00209          if (demodulador(zap,&x2)) return(-1);
    00210          if (x1>0 && x2<0) break;
    00211          x1=x2;
    00212       }
    00213 */
    00214 /* this is now the imprecise, losing, but functional code to detect the
    00215 beginning of a start bit in the TDD sceanario. It just looks for sufficient
    00216 level to maybe, perhaps, guess, maybe that its maybe the beginning of
    00217 a start bit, perhaps. This whole thing stinks! */
    00218       beginlenx=beginlen; /* just to avoid unused war warnings */
    00219       if (demodulador(fskd,&fskd->x1,GET_SAMPLE)) return(-1);
    00220       samples++;
    00221       for(;;)
    00222          {
    00223 search_startbit2:
    00224          if (*len <= 0) {
    00225             fskd->state = STATE_SEARCH_STARTBIT2;
    00226             return 0;
    00227          }
    00228          samples++;
    00229          if (demodulador(fskd,&fskd->x2,GET_SAMPLE)) return(-1);
    00230 #if 0
    00231          printf("x2 = %5.5f ", fskd->x2);
    00232 #endif
    00233          if (fskd->x2 < -0.5) break;
    00234          }
    00235 search_startbit3:
    00236       /* Esperamos 0.5 bits antes de usar DPLL */
    00237       i=fskd->spb/2;
    00238       if (*len < i) {
    00239          fskd->state = STATE_SEARCH_STARTBIT3;
    00240          return 0;
    00241       }
    00242       for(;i>0;i--) { if (demodulador(fskd,&fskd->x1,GET_SAMPLE)) return(-1);
    00243 #if 0
    00244          printf("x1 = %5.5f ", fskd->x1);
    00245 #endif
    00246    samples++; }
    00247
    00248       /* x1 debe ser negativo (confirmación del bit de start) */
    00249
    00250    } while (fskd->x1>0);
    00251    fskd->state = STATE_GET_BYTE;
    00252
    00253 getbyte:
    00254
    00255    /* Need at least 80 samples (for 1200) or
    00256       1320 (for 45.5) to be sure we'll have a byte */
    00257    if (fskd->nbit < 8) {
    00258       if (*len < 1320)
    00259          return 0;
    00260    } else {
    00261       if (*len < 80)
    00262          return 0;
    00263    }
    00264    /* Leemos ahora los bits de datos */
    00265    j=fskd->nbit;
    00266    for (a=n1=0;j;j--) {
    00267       olen = *len;
    00268       i=get_bit_raw(fskd, buffer, len);
    00269       buffer += (olen - *len);
    00270       if (i == -1) return(-1);
    00271       if (i) n1++;
    00272       a>>=1; a|=i;
    00273    }
    00274    j=8-fskd->nbit;
    00275    a>>=j;
    00276
    00277    /* Leemos bit de paridad (si existe) y la comprobamos */
    00278    if (fskd->paridad) {
    00279       olen = *len;
    00280       i=get_bit_raw(fskd, buffer, len);
    00281       buffer += (olen - *len);
    00282       if (i == -1) return(-1);
    00283       if (i) n1++;
    00284       if (fskd->paridad==1) { /* paridad=1 (par) */
    00285          if (n1&1) a|=0x100;     /* error */
    00286       } else {       /* paridad=2 (impar) */
    00287          if (!(n1&1)) a|=0x100;  /* error */
    00288       }
    00289    }
    00290
    00291    /* Leemos bits de STOP. Todos deben ser 1 */
    00292
    00293    for (j=fskd->nstop;j;j--) {
    00294       r = get_bit_raw(fskd, buffer, len);
    00295       if (r == -1) return(-1);
    00296       if (!r) a|=0x200;
    00297    }
    00298
    00299    /* Por fin retornamos  */
    00300    /* Bit 8 : Error de paridad */
    00301    /* Bit 9 : Error de Framming */
    00302
    00303    *outbyte = a;
    00304    fskd->state = STATE_SEARCH_STARTBIT;
    00305    return 1;
    00306 }

static int get_bit_raw | ( | fsk_data * | fskd,
|  | short * | buffer,
|  | int * | len |
| ) |  |  | `[static]`

Definition at line 152 of file fskmodem.c.

References fsk_data::cont, demodulador(), GET_SAMPLE, fsk_data::spb, and fsk_data::x0.

Referenced by fsk_serie().

    00153 {
    00154    /* Esta funcion implementa un DPLL para sincronizarse con los bits */
    00155    float x,spb,spb2,ds;
    00156    int f;
    00157
    00158    spb=fskd->spb;
    00159    if (fskd->spb == 7) spb = 8000.0 / 1200.0;
    00160    ds=spb/32.;
    00161    spb2=spb/2.;
    00162
    00163    for (f=0;;){
    00164       if (demodulador(fskd,&x, GET_SAMPLE)) return(-1);
    00165       if ((x*fskd->x0)<0) {   /* Transicion */
    00166          if (!f) {
    00167             if (fskd->cont<(spb2)) fskd->cont+=ds; else fskd->cont-=ds;
    00168             f=1;
    00169          }
    00170       }
    00171       fskd->x0=x;
    00172       fskd->cont+=1.;
    00173       if (fskd->cont>spb) {
    00174          fskd->cont-=spb;
    00175          break;
    00176       }
    00177    }
    00178    f=(x>0)?0x80:0;
    00179    return(f);
    00180 }

static float get_sample | ( | short ** | buffer,
|  | int * | len |
| ) |  |  | `[inline, static]`

Definition at line 45 of file fskmodem.c.

    00046 {
    00047    float retval;
    00048    retval = (float) **buffer / 256;
    00049    (*buffer)++;
    00050    (*len)--;
    00051    return retval;
    00052 }

## Variable Documentation

double coef_in[NF][NBW][8]`[static]`

Definition at line 62 of file fskmodem.c.

double coef_out[NBW][8]`[static]`

Definition at line 72 of file fskmodem.c.