⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v32tx.c

📁 Fax and soft modem source code. - Fast Version You can use this code to build a soft modem functi
💻 C
字号:
// #include <stdio.h>
#include <coro.h>

#include <complex.h>
#include <scramble.h>
#include <sinegen.h>
#include <myaudio.h>
#include <mystdio.h>

#include "modem.h"
#include "cancel.h"
#include "coder.h"

#define TX_TRNLEN   8000	/* length of training sequence transmitted (WAS 4096) */

static float shapetab[2*SYMBLEN+1] =
  { /* Raised cosine pulse shaping with Beta = 0.5; square-root, with x/sinx compensation */
    +1.1510798492, +0.9848450677, +0.5795790021, +0.1495226763,
    -0.1156411181, -0.1625782395, -0.0750914609, +0.0185567369,
    +0.0448950047,
  };

static sinegen *carrier;
static coroutine *tx1_co, *tx2_co;
static scrambler *gpc;
static traininggen *trn;
static encoder *enc;

static void sendrate(ushort);
static void tx2_loop();
static void sendsymbol(complex);

inline void pbit(int b) { callco(tx2_co, b);	 }
inline int gbit()	{ return callco(tx1_co); }


global void inittx()
  { carrier = new sinegen(1800.0);
    tx1_co = currentco;
    tx2_co = new coroutine(tx2_loop);
    gpc = new scrambler(GPC);
    trn = new traininggen(gpc);
    enc = new encoder;
    pbit(1);					    /* sync to symbol boundary */
    ushort r2 = rateword;
    infomsg(">>> R2: rates = %04x", r2);
    while (mstate < 5) sendrate(r2);		    /* send R2 */
    /* now rateword == R2 & R3 */
    rateword |= 0xf000;
    /* pick highest common bit rate, leave just one rate bit set */
    if (rateword & rb_14400) rateword &= ~(rb_12000 | rb_9600 | rb_7200 | rb_4800);
    else if (rateword & rb_12000) rateword &= ~(rb_9600 | rb_7200 | rb_4800);
    else if (rateword & rb_9600) rateword &= ~(rb_7200 | rb_4800);
    else if (rateword & rb_7200) rateword &= ~rb_4800;
    else if (rateword & rb_4800) ;
    else giveup("can't agree on a speed!");
    infomsg(">>> E2: rates = %04x", rateword);      /* send E2 */
    sendrate(rateword);
    enc -> setrate(rateword);			    /* tell encoder what bit rate to use */
    while (mstate < 6) pbit(1);			    /* sync to Rx side */
    for (int i = 0; i < 128; i++) pbit(1);	    /* followed by 128 "1" bits */
  }

static void sendrate(ushort wd)
  { for (int i=0; i < 16; i++) { pbit(wd >> 15); wd <<= 1; }
  }

global void putasync(int n)			/* asynchronous output */
  { uint un = (n >= 0) ? (n << 1) | 0x200 :	/* add start bit, 1 stop bit */
			 0x3ff;			/* send mark bits while idle */
    until (un == 0) { pbit(un & 1); un >>= 1; }
  }

static void tx2_loop()
  { /* round-trip-delay estimation */
    while (mstate < 2)
      { complex z = (mstate == 0) ? ztab2[0] : ztab2[3];	/* A or C */
	sendsymbol(z); sendsymbol(z);	/* AA or CC */
      }
    /* train equalizer */
    while (mstate == 2) sendsymbol(0.0);
    /* train canceller */
    carrier -> resetphase();
    gpc -> reset();	/* reset scrambler before using trn */
    for (int bc = SEG_1; bc < SEG_3 + TX_TRNLEN; bc++) sendsymbol(trn -> get(bc));
    mstate++;		/* from 3 to 4 */
    /* exchange data */
    enc -> reset();
    for (;;)
      { int bits = 0;
	bits = (bits << 1) | gpc -> fwd(gbit());
	bits = (bits << 1) | gpc -> fwd(gbit());
	if (enc -> rate & rb_7200) bits = (bits << 1) | gpc -> fwd(gbit());
	sendsymbol(enc -> encode(bits));
      }
  }

static void sendsymbol(complex z)
  { static complex a0 = 0.0, a1 = 0.0, a2 = 0.0, a3 = 0.0;
    for (int k = 0; k < SYMBLEN; k++)
      { /* baseband pulse shaping */
	complex s = shapetab[SYMBLEN + k]   * a0
		  + shapetab[k]		    * a1
		  + shapetab[SYMBLEN - k]   * a2
		  + shapetab[2*SYMBLEN - k] * a3;
	/* insert baseband sample into canceller */
	can -> insert(s);
	/* modulate onto carrier */
	complex cz = carrier -> cnext();
	outsample(0.2f * (s.re*cz.re + s.im*cz.im));
      }
    a0 = a1; a1 = a2; a2 = a3; a3 = z;
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -