/soundmodem-0.15/newqpsk/newqpsktx.c

# · C · 382 lines · 266 code · 72 blank · 44 comment · 43 complexity · 9a3d4e58d771f471bfbb9110ea86c7b7 MD5 · raw file

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <time.h>
  5. #include <math.h>
  6. #include "modem.h"
  7. #include "modemconfig.h"
  8. #include "complex.h"
  9. #include "fec.h"
  10. #include "filter.h"
  11. #include "newqpsktx.h"
  12. #include "tbl.h"
  13. #include "misc.h"
  14. /* --------------------------------------------------------------------- */
  15. static void txtune(void *);
  16. static void txsync(void *);
  17. static void txpredata(void *);
  18. static void txdata(void *);
  19. static void txpostdata(void *);
  20. static void txjam(void *);
  21. static void txflush(void *);
  22. /* --------------------------------------------------------------------- */
  23. void init_newqpsktx(void *state)
  24. {
  25. struct txstate *s = (struct txstate *)state;
  26. int i;
  27. /* switch to tune mode */
  28. s->txroutine = txtune;
  29. s->statecntr = s->tunelen;
  30. s->txwindowfunc = ToneWindowOut;
  31. /* copy initial tune vectors */
  32. for (i = 0; i < TuneCarriers; i++) {
  33. s->tunevect[i].re = TuneIniVectI[i];
  34. s->tunevect[i].im = TuneIniVectQ[i];
  35. }
  36. }
  37. /* --------------------------------------------------------------------- */
  38. static int getbyte(void *state, unsigned char *buf)
  39. {
  40. struct txstate *s = (struct txstate *)state;
  41. if (s->saved != -1) {
  42. *buf = (unsigned char) s->saved;
  43. s->saved = -1;
  44. return 1;
  45. }
  46. return pktget(s->chan, buf, 1);
  47. }
  48. static unsigned int getbitbatch(void *state)
  49. {
  50. struct txstate *s = (struct txstate *)state;
  51. unsigned int i, bit, data = 0;
  52. unsigned char buf;
  53. for (i = 0; i < s->fec.bitbatchlen; i++) {
  54. if (s->shreg <= 1) {
  55. if (!getbyte(s, &buf))
  56. break;
  57. s->shreg = buf;
  58. s->shreg |= 0x100;
  59. }
  60. bit = s->shreg & 1;
  61. s->shreg >>= 1;
  62. data |= bit << i;
  63. }
  64. if (i == s->fec.bitbatchlen)
  65. s->empty = 0;
  66. else
  67. s->empty = 1;
  68. return data;
  69. }
  70. /* --------------------------------------------------------------------- */
  71. static void fft(complex * in, complex * out)
  72. {
  73. int i, j, k;
  74. int s, sep, width, top, bot;
  75. float tr, ti;
  76. /* order the samples in bit reverse order */
  77. for (i = 0; i < WindowLen; i++) {
  78. j = rbits8(i) >> (8 - WindowLenLog);
  79. out[j] = in[i];
  80. }
  81. /* in-place FFT */
  82. sep = 1;
  83. for (s = 1; s <= WindowLenLog; s++) {
  84. width = sep; /* butterfly width = 2^(s-1) */
  85. sep <<= 1; /* butterfly separation = 2^s */
  86. for (j = 0; j < width; j++) {
  87. k = WindowLen * j / sep;
  88. for (top = j; top < WindowLen; top += sep) {
  89. bot = top + width;
  90. tr = out[bot].re * CosTable[k] + out[bot].im * SinTable[k];
  91. ti = out[bot].im * CosTable[k] - out[bot].re * SinTable[k];
  92. out[bot].re = out[top].re - tr;
  93. out[bot].im = out[top].im - ti;
  94. out[top].re = out[top].re + tr;
  95. out[top].im = out[top].im + ti;
  96. }
  97. }
  98. }
  99. }
  100. /* --------------------------------------------------------------------- */
  101. int newqpsktx(void *state, complex *samples)
  102. {
  103. struct txstate *s = (struct txstate *)state;
  104. complex tmp[WindowLen];
  105. int i;
  106. /* clear all FFT bins */
  107. for (i = 0; i < WindowLen; i++) {
  108. s->fftbuf[i].re = 0.0;
  109. s->fftbuf[i].im = 0.0;
  110. }
  111. /* process the data */
  112. if (!s->tuneonly)
  113. s->txroutine(state);
  114. else
  115. txtune(state);
  116. /* fft */
  117. fft(s->fftbuf, tmp);
  118. /* overlap and apply the window function */
  119. i = 0;
  120. while (i < WindowLen - SymbolLen) {
  121. s->txwin[i] = s->txwin[i + SymbolLen];
  122. s->txwin[i].re += tmp[i].re * s->txwindowfunc[i];
  123. s->txwin[i].im += tmp[i].im * s->txwindowfunc[i];
  124. i++;
  125. }
  126. while (i < WindowLen) {
  127. s->txwin[i].re = tmp[i].re * s->txwindowfunc[i];
  128. s->txwin[i].im = tmp[i].im * s->txwindowfunc[i];
  129. i++;
  130. }
  131. /* output filter and interpolation */
  132. i = filter(&s->filt, s->txwin, samples);
  133. return i;
  134. }
  135. /* --------------------------------------------------------------------- */
  136. /*
  137. * Send tune carriers (four continuous carriers spaced at 600Hz).
  138. */
  139. static void txtune(void *state)
  140. {
  141. struct txstate *s = (struct txstate *)state;
  142. int i, j;
  143. j = FirstTuneCarr;
  144. for (i = 0; i < TuneCarriers; i++) {
  145. /* flip odd carriers -> continuous phase */
  146. if (j % 2) {
  147. s->fftbuf[j].re = -s->tunevect[i].re;
  148. s->fftbuf[j].im = -s->tunevect[i].im;
  149. } else {
  150. s->fftbuf[j].re = s->tunevect[i].re;
  151. s->fftbuf[j].im = s->tunevect[i].im;
  152. }
  153. s->tunevect[i] = s->fftbuf[j];
  154. j += TuneCarrSepar;
  155. }
  156. if (!s->tuneonly && --s->statecntr <= 0) {
  157. /* switch to sync mode */
  158. s->txroutine = txsync;
  159. s->statecntr = s->synclen;
  160. s->txwindowfunc = DataWindowOut;
  161. }
  162. }
  163. /* --------------------------------------------------------------------- */
  164. /*
  165. * Send sync sequence (tune carriers turned by 180 degrees every symbol).
  166. */
  167. static void txsync(void *state)
  168. {
  169. struct txstate *s = (struct txstate *)state;
  170. int i, j;
  171. j = FirstTuneCarr;
  172. for (i = 0; i < TuneCarriers; i++) {
  173. /* flip even carriers -> inverted phase */
  174. if (j % 2) {
  175. s->fftbuf[j].re = s->tunevect[i].re;
  176. s->fftbuf[j].im = s->tunevect[i].im;
  177. } else {
  178. s->fftbuf[j].re = -s->tunevect[i].re;
  179. s->fftbuf[j].im = -s->tunevect[i].im;
  180. }
  181. s->tunevect[i] = s->fftbuf[j];
  182. j += TuneCarrSepar;
  183. }
  184. if (--s->statecntr <= 0) {
  185. /* switch to pre data mode */
  186. s->txroutine = txpredata;
  187. s->statecntr = TxPreData;
  188. /* copy initial data vectors */
  189. for (i = 0; i < DataCarriers; i++) {
  190. s->datavect[i].re = DataIniVectI[i];
  191. s->datavect[i].im = DataIniVectQ[i];
  192. }
  193. /* initialise the interleaver */
  194. init_inlv(&s->fec);
  195. }
  196. }
  197. /* --------------------------------------------------------------------- */
  198. static void encodeword(void *state, int jam)
  199. {
  200. struct txstate *s = (struct txstate *)state;
  201. unsigned i, j, k, data;
  202. complex z;
  203. float phi;
  204. /* run through interleaver only if not jamming */
  205. if (!jam) {
  206. for (i = 0; i < SymbolBits; i++)
  207. s->txword[i] = inlv(&s->fec, s->txword[i]);
  208. }
  209. j = FirstDataCarr;
  210. for (i = 0; i < DataCarriers; i++) {
  211. /* collect databits for this symbol */
  212. data = 0;
  213. for (k = 0; k < SymbolBits; k++) {
  214. data <<= 1;
  215. if (s->txword[k] & (1 << i))
  216. data |= 1;
  217. }
  218. /* gray encode */
  219. data ^= data >> 1;
  220. /* flip the top bit */
  221. data ^= 1 << (SymbolBits - 1);
  222. /* modulate */
  223. phi = data * 2 * M_PI / PhaseLevels;
  224. /* if jamming, turn by maximum phase error */
  225. if (jam)
  226. phi += M_PI / PhaseLevels;
  227. z.re = cos(phi);
  228. z.im = sin(phi);
  229. s->fftbuf[j] = cmul(s->datavect[i], z);
  230. /* turn odd carriers by 180 degrees */
  231. if (j % 2) {
  232. s->fftbuf[j].re = -s->fftbuf[j].re;
  233. s->fftbuf[j].im = -s->fftbuf[j].im;
  234. }
  235. s->datavect[i] = s->fftbuf[j];
  236. j += DataCarrSepar;
  237. }
  238. }
  239. static void txpredata(void *state)
  240. {
  241. struct txstate *s = (struct txstate *)state;
  242. int i;
  243. for (i = 0; i < SymbolBits; i++)
  244. s->txword[i] = 0;
  245. encodeword(state, 0);
  246. if (--s->statecntr <= 0) {
  247. /* switch to data mode */
  248. s->txroutine = txdata;
  249. }
  250. }
  251. static void txdata(void *state)
  252. {
  253. struct txstate *s = (struct txstate *)state;
  254. int i;
  255. for (i = 0; i < SymbolBits; i++) {
  256. s->txword[i] = getbitbatch(state);
  257. s->txword[i] = fecencode(&s->fec, s->txword[i]);
  258. }
  259. encodeword(state, 0);
  260. if (s->empty) {
  261. /* switch to post data mode */
  262. s->txroutine = txpostdata;
  263. s->statecntr = TxPostData + (s->fec.inlv * DataCarriers + 1) / SymbolBits;
  264. }
  265. }
  266. static void txpostdata(void *state)
  267. {
  268. struct txstate *s = (struct txstate *)state;
  269. int i;
  270. for (i = 0; i < SymbolBits; i++)
  271. s->txword[i] = 0;
  272. encodeword(state, 0);
  273. #if 0
  274. if (!hdlc_txempty(&s->hdlc)) {
  275. /* there is new data - switch back to data mode */
  276. s->txroutine = txdata;
  277. return;
  278. }
  279. #endif
  280. if (--s->statecntr <= 0) {
  281. /* switch to jamming mode */
  282. s->txroutine = txjam;
  283. s->statecntr = TxJamLen;
  284. srand(time(NULL));
  285. }
  286. }
  287. static void txjam(void *state)
  288. {
  289. struct txstate *s = (struct txstate *)state;
  290. int i;
  291. for (i = 0; i < SymbolBits; i++)
  292. s->txword[i] = rand();
  293. encodeword(state, 1);
  294. if (--s->statecntr <= 0) {
  295. /* switch to buffer flush mode */
  296. s->txroutine = txflush;
  297. s->statecntr = 3;
  298. }
  299. }
  300. static void txflush(void *state)
  301. {
  302. struct txstate *s = (struct txstate *)state;
  303. if (--s->statecntr <= 0) {
  304. /* get ready for the next transmission */
  305. init_newqpsktx(state);
  306. /* signal the main routine we're done */
  307. s->txdone = 1;
  308. }
  309. }
  310. /* --------------------------------------------------------------------- */