www.pudn.com > slow.zip > fskrx.C


/********************************************************* 
********************************************************** 
	fskrx.c 
********************************************************** 
**********************************************************/ 
#line 1 "fskrx.F" 
/* Modem for MIPS   AJF	  January 1995 
   FSK receive routines */ 
 
#include  
 
#include  
#include  
#line 1 "<>" 
 
static float _fstepf_1(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Hp -Bu -o 2 -a 0.03125 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2];  
    v[2] =    (  8.7033077934e-01 * x) 
            + ( -0.7575469445 * v[0]) + (  1.7237761728 * v[1]); 
    return    (v[0] + v[2]) - 2 * v[1]; 
  } 
 
static fspec _fspecs_1 = { 2, 2, _fstepf_1 }; 
 
static float _fstepf_2(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Bp -o 4 -a 0.03593750000 0.04531250000 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] = v[5]; v[5] = v[6]; v[6] = v[7]; v[7] = v[8];  
    v[8] =    (  6.9752013701e-07 * x) 
            + ( -0.8573132535 * v[0]) + (  6.7668969461 * v[1]) 
            + (-23.5932085800 * v[2]) + ( 47.4460745570 * v[3]) 
            + (-60.1843751000 * v[4]) + ( 49.3079205940 * v[5]) 
            + (-25.4811693030 * v[6]) + (  7.5951586426 * v[7]); 
    return    (v[0] + v[8]) - 4 * (v[2] + v[6]) + 6 * v[4]; 
  } 
 
static fspec _fspecs_2 = { 8, 8, _fstepf_2 }; 
 
static float _fstepf_3(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Bp -o 4 -a 0.04218750000 0.05156250000 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] = v[5]; v[5] = v[6]; v[6] = v[7]; v[7] = v[8];  
    v[8] =    (  6.9752016299e-07 * x) 
            + ( -0.8573132535 * v[0]) + (  6.6923550121 * v[1]) 
            + (-23.1543073350 * v[2]) + ( 46.3522570580 * v[3]) 
            + (-58.7085652640 * v[4]) + ( 48.1711764630 * v[5]) 
            + (-25.0071445210 * v[6]) + (  7.5114928473 * v[7]); 
    return    (v[0] + v[8]) - 4 * (v[2] + v[6]) + 6 * v[4]; 
  } 
 
static fspec _fspecs_3 = { 8, 8, _fstepf_3 }; 
 
static float _fstepf_4(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Bp -o 4 -a 0.08645833333 0.11770833333 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] = v[5]; v[5] = v[6]; v[6] = v[7]; v[7] = v[8];  
    v[8] =    (  7.2772549304e-05 * x) 
            + ( -0.5980652616 * v[0]) + (  4.0990376798 * v[1]) 
            + (-13.2484867760 * v[2]) + ( 25.9936474290 * v[3]) 
            + (-33.7188652410 * v[4]) + ( 29.5600799340 * v[5]) 
            + (-17.1334523570 * v[6]) + (  6.0282616021 * v[7]); 
    return    (v[0] + v[8]) - 4 * (v[2] + v[6]) + 6 * v[4]; 
  } 
 
static fspec _fspecs_4 = { 8, 8, _fstepf_4 }; 
 
static float _fstepf_5(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Bp -o 4 -a 0.10729166667 0.13854166667 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] = v[5]; v[5] = v[6]; v[6] = v[7]; v[7] = v[8];  
    v[8] =    (  7.2772549293e-05 * x) 
            + ( -0.5980652616 * v[0]) + (  3.6644426643 * v[1]) 
            + (-11.1300599420 * v[2]) + ( 21.0682850680 * v[3]) 
            + (-27.0350338160 * v[4]) + ( 23.9582210380 * v[5]) 
            + (-14.3932202710 * v[6]) + (  5.3891231873 * v[7]); 
    return    (v[0] + v[8]) - 4 * (v[2] + v[6]) + 6 * v[4]; 
  } 
 
static fspec _fspecs_5 = { 8, 8, _fstepf_5 }; 
 
static float _fstepf_6(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Bp -o 4 -a 0.07291666667 0.19791666667 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] = v[5]; v[5] = v[6]; v[6] = v[7]; v[7] = v[8];  
    v[8] =    (  1.0209485168e-02 * x) 
            + ( -0.1203895999 * v[0]) + (  0.8607078056 * v[1]) 
            + ( -3.0834704657 * v[2]) + (  6.9712707669 * v[3]) 
            + (-10.8265470100 * v[4]) + ( 11.8178544010 * v[5]) 
            + ( -8.9162166465 * v[6]) + (  4.2594924397 * v[7]); 
    return    (v[0] + v[8]) - 4 * (v[2] + v[6]) + 6 * v[4]; 
  } 
 
static fspec _fspecs_6 = { 8, 8, _fstepf_6 }; 
 
static float _fstepf_7(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Bp -o 4 -a 0.15625000000 0.18750000000 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] = v[5]; v[5] = v[6]; v[6] = v[7]; v[7] = v[8];  
    v[8] =    (  7.2772549288e-05 * x) 
            + ( -0.5980652616 * v[0]) + (  2.4115616747 * v[1]) 
            + ( -6.3503651535 * v[2]) + ( 10.6437685460 * v[3]) 
            + (-13.4950048970 * v[4]) + ( 12.1025995180 * v[5]) 
            + ( -8.2105790765 * v[6]) + (  3.5465701416 * v[7]); 
    return    (v[0] + v[8]) - 4 * (v[2] + v[6]) + 6 * v[4]; 
  } 
 
static fspec _fspecs_7 = { 8, 8, _fstepf_7 }; 
 
static float _fstepf_8(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Bp -o 4 -a 0.17708333333 0.20833333333 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] = v[5]; v[5] = v[6]; v[6] = v[7]; v[7] = v[8];  
    v[8] =    (  7.2772549288e-05 * x) 
            + ( -0.5980652616 * v[0]) + (  1.8020335084 * v[1]) 
            + ( -4.7377941052 * v[2]) + (  7.1414399699 * v[3]) 
            + ( -9.4084488721 * v[4]) + (  8.1198574059 * v[5]) 
            + ( -6.1246826679 * v[6]) + (  2.6501657835 * v[7]); 
    return    (v[0] + v[8]) - 4 * (v[2] + v[6]) + 6 * v[4]; 
  } 
 
static fspec _fspecs_8 = { 8, 8, _fstepf_8 }; 
 
static float _fstepf_9(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Bp -o 4 -a 0.15625000000 0.28125000000 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] = v[5]; v[5] = v[6]; v[6] = v[7]; v[7] = v[8];  
    v[8] =    (  1.0209480791e-02 * x) 
            + ( -0.1203895999 * v[0]) + (  0.2546702491 * v[1]) 
            + ( -0.9309959180 * v[2]) + (  1.2682731462 * v[3]) 
            + ( -2.4167363057 * v[4]) + (  2.1128659855 * v[5]) 
            + ( -2.5766910046 * v[6]) + (  1.2603185349 * v[7]); 
    return    (v[0] + v[8]) - 4 * (v[2] + v[6]) + 6 * v[4]; 
  } 
 
static fspec _fspecs_9 = { 8, 8, _fstepf_9 }; 
 
static float _fstepf_10(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Lp -o 4 -a 0.00390625 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] =    (  2.1968455520e-08 * x) 
            + ( -0.9378758961 * v[0]) + (  3.8116542349 * v[1]) 
            + ( -5.8096437117 * v[2]) + (  3.9358650214 * v[3]); 
    return    (v[0] + v[4]) + 4 * (v[1] + v[3]) + 6 * v[2]; 
  } 
 
static fspec _fspecs_10 = { 4, 4, _fstepf_10 }; 
 
static float _fstepf_11(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Lp -o 4 -a 0.01562500 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] =    (  5.1232059674e-06 * x) 
            + ( -0.7736282195 * v[0]) + (  3.2929432847 * v[1]) 
            + ( -5.2629037982 * v[2]) + (  3.7435067617 * v[3]); 
    return    (v[0] + v[4]) + 4 * (v[1] + v[3]) + 6 * v[2]; 
  } 
 
static fspec _fspecs_11 = { 4, 4, _fstepf_11 }; 
 
static float _fstepf_12(filter *fi, float x) 
  { /* /usr/fisher/mipsbin/mkfilter -Bu -Lp -o 4 -a 0.06250000 -l */ 
    float *v = fi -> v; 
    v[0] = v[1]; v[1] = v[2]; v[2] = v[3]; v[3] = v[4];  
    v[4] =    (  9.3349861292e-04 * x) 
            + ( -0.3555773823 * v[0]) + (  1.7861066002 * v[1]) 
            + ( -3.4223095294 * v[2]) + (  2.9768443337 * v[3]); 
    return    (v[0] + v[4]) + 4 * (v[1] + v[3]) + 6 * v[2]; 
  } 
 
static fspec _fspecs_12 = { 4, 4, _fstepf_12 }; 
 
#line 8 "fskrx.F" 
#include  
#include  
#include  
 
#include "modem.h" 
 
static fspec *fefs = (&_fspecs_1);       /* 300 Hz hpf */ 
 
/* Bandpass filter coeffs constructed by: 
   mkfilter -Bu -Bp -o 2 -a (A1) (A2) 
   where A1 = (F0 - bps/2) / SAMPLERATE, A2 = (F0 + bps/2) / SAMPLERATE */ 
 
static fspec *bpfspecs[] = 
  { (&_fspecs_2),    /*  345 ..  435 Hz, centre  390 Hz    [0] */ 
    (&_fspecs_3),    /*  405 ..  495 Hz, centre  450 Hz    [1] */ 
    (&_fspecs_4),    /*  830 .. 1130 Hz, centre  980 Hz    [2] */ 
    (&_fspecs_5),    /* 1030 .. 1330 Hz, centre 1180 Hz    [3] */ 
    (&_fspecs_6),    /*  700 .. 1900 Hz, centre 1300 Hz    [4] */ 
    (&_fspecs_7),    /* 1500 .. 1800 Hz, centre 1650 Hz    [5] */ 
    (&_fspecs_8),    /* 1700 .. 2000 Hz, centre 1850 Hz    [6] */ 
    (&_fspecs_9),    /* 1500 .. 2700 Hz, centre 2100 Hz    [7] */ 
  }; 
 
/* Lpwpass filter coeffs constructed by: 
   mkfilter -Bu -Lp -o 2 -a (A1) 
   where A1 = (bps/2) / SAMPLERATE */ 
 
static fspec *lpfspecs[] = 
  { (&_fspecs_10),     /*  37.5 Hz   [0] */ 
    (&_fspecs_11),     /* 150   Hz   [1] */ 
    (&_fspecs_12),     /* 600   Hz   [2] */ 
  }; 
 
struct info 
  { int bitlen;		    /* bit length (num. samples)	    */ 
    fspec *lpfs;	    /* low-pass filter spec		    */ 
    fspec *bpfs0, *bpfs1;   /* bandpass filter specs for 0, 1 tones */ 
  }; 
 
static info infotab[] = 
  { {  32, lpfspecs[1], bpfspecs[6], bpfspecs[5] },	/* V21o	  300 bps */ 
    {  32, lpfspecs[1], bpfspecs[3], bpfspecs[2] },	/* V21a	  300 bps */ 
    {	8, lpfspecs[2], bpfspecs[7], bpfspecs[4] },	/* V23o	 1200 bps */ 
    { 128, lpfspecs[0], bpfspecs[1], bpfspecs[0] },	/* V23a	   75 bps */ 
  }; 
 
static int bitlen; 
 
static bool inited = false;	/* statically initialized */ 
 
static coroutine *syncco; 
static tone_detector *td0, *td1; 
 
static void syncloop(); 
static int getsample(); 
 
 
global void initrx_fsk(vmode mode) 
  { if (inited) { delete td0; delete td1; } 
    unless (inited)	/* once-only initialization */ 
      { syncco = new coroutine(syncloop); 
	inited = true; 
      } 
    unless (mode >= 0 && mode < 4) giveup("Bug! bad mode %d in fsk rx init", mode); 
    info *inf = &infotab[mode]; 
    td0 = new tone_detector(fefs, inf -> bpfs0, inf -> lpfs, false); 
    td1 = new tone_detector(fefs, inf -> bpfs1, inf -> lpfs, false); 
    bitlen = inf -> bitlen; /* num. samples in a bit */ 
    syncco -> reset(); 
  } 
 
global int getasync()	    /* asynchronous input */ 
  { int i, j; uchar n; 
    int b = getsample(), nb = 0; 
    while (nb < 10*bitlen && b) { b = getsample(); nb++; } 
    if (b) return NOCHAR;   /* no char yet */ 
    for (j = 0; j < (3*bitlen)/2; j++) b = getsample();	   /* position to centre of first data bit */ 
    for (i = 0; i < 8; i++) 
      { n = (n >> 1) | (b << 7); 
	for (j = 0; j < bitlen; j++) b = getsample(); 
      } 
    return n; 
  } 
 
global int getsync()	    /* synchronous input */ 
  { return callco(syncco); 
  } 
 
static void syncloop() 
  { uchar valid = 0, framing = 0x55, bitcount = 0; 
    uchar bits, byte; 
    for (;;) 
      { int j = 0; int bit; 
	while (j < bitlen) 
	  { bit = getsample(); 
	    framing = (framing << 1) | bit; 
	    j = (framing == 0xf0 || framing == 0x0f) ? (bitlen/2)+4 : j+1; 
	  } 
	bits = (bits << 1) | bit; 
	valid = (valid << 1) | 1; 
	switch (bits) 
	  { case 0x7c:	case 0x7d: 
		valid &= ~2;	/* delete bit-stuffing */ 
		break; 
 
	    case 0x7e: 
		callco(currentco -> creator, HDLC_FLAG);	/* return a flag */ 
		valid = bitcount = 0; 
		break; 
 
	    case 0x7f: 
		callco(currentco -> creator, HDLC_ABORT);	/* return an abort */ 
		valid = bitcount = 0; 
		break; 
	  } 
	if (valid & 0x80) 
	  { byte = (byte << 1) | (bits >> 7); 
	    if (++bitcount == 8) 
	      { callco(currentco -> creator, byte);		/* return a regular byte */ 
		bitcount = 0; 
	      } 
	  } 
      } 
  } 
 
static int getsample() 
  { float x = insample(); 
    td0 -> insert(x); td1 -> insert(x); 
    return (td1 -> pow) > (td0 -> pow); 
  }