fskmodem_int.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * Includes code and algorithms from the Zapata library.
  9. *
  10. * See http://www.asterisk.org for more information about
  11. * the Asterisk project. Please do not directly contact
  12. * any of the maintainers of this project for assistance;
  13. * the project provides a web site, mailing lists and IRC
  14. * channels for your use.
  15. *
  16. * This program is free software, distributed under the terms of
  17. * the GNU General Public License Version 2. See the LICENSE file
  18. * at the top of the source tree.
  19. */
  20. /*! \file
  21. *
  22. * \brief FSK Modulator/Demodulator
  23. *
  24. * \author Mark Spencer <markster@digium.com>
  25. *
  26. * \arg Includes code and algorithms from the Zapata library.
  27. *
  28. */
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  31. #include "asterisk/fskmodem.h"
  32. #define NBW 2
  33. #define BWLIST {75,800}
  34. #define NF 6
  35. #define FLIST {1400,1800,1200,2200,1300,2100}
  36. #define STATE_SEARCH_STARTBIT 0
  37. #define STATE_SEARCH_STARTBIT2 1
  38. #define STATE_SEARCH_STARTBIT3 2
  39. #define STATE_GET_BYTE 3
  40. static inline int iget_sample(short **buffer, int *len)
  41. {
  42. int retval;
  43. retval = (int) **buffer;
  44. (*buffer)++;
  45. (*len)--;
  46. return retval;
  47. }
  48. #define IGET_SAMPLE iget_sample(&buffer, len)
  49. /*! \brief Coefficients for input filters
  50. * Coefficients table, generated by program "mkfilter"
  51. * mkfilter is part of the zapatatelephony.org distribution
  52. * Format: coef[IDX_FREC][IDX_BW][IDX_COEF]
  53. * IDX_COEF = 0 => 1/GAIN
  54. * IDX_COEF = 1-6 => Coefficientes y[n]
  55. */
  56. static double coef_in[NF][NBW][8]={
  57. { { 1.8229206611e-04,-7.8997325866e-01,2.2401819940e+00,-4.6751353581e+00,5.5080745712e+00,-5.0571565772e+00,2.6215820004e+00,0.0000000000e+00,
  58. }, { 9.8532175289e-02,-5.6297236492e-02,3.3146713415e-01,-9.2239200436e-01,1.4844365184e+00,-2.0183258642e+00,2.0074154497e+00,0.0000000000e+00,
  59. }, }, { { 1.8229206610e-04,-7.8997325866e-01,7.7191410839e-01,-2.8075643964e+00,1.6948618347e+00,-3.0367273700e+00,9.0333559408e-01,0.0000000000e+00,
  60. }, { 9.8531161839e-02,-5.6297236492e-02,1.1421579050e-01,-4.8122536483e-01,4.0121072432e-01,-7.4834487567e-01,6.9170822332e-01,0.0000000000e+00,
  61. }, }, { { 1.8229206611e-04,-7.8997325866e-01,2.9003821430e+00,-6.1082779024e+00,7.7169345751e+00,-6.6075999680e+00,3.3941838836e+00,0.0000000000e+00,
  62. }, { 9.8539686961e-02,-5.6297236492e-02,4.2915323820e-01,-1.2609358633e+00,2.2399213250e+00,-2.9928879142e+00,2.5990173742e+00,0.0000000000e+00,
  63. }, }, { { 1.8229206610e-04,-7.8997325866e-01,-7.7191410839e-01,-2.8075643964e+00,-1.6948618347e+00,-3.0367273700e+00,-9.0333559408e-01,0.0000000000e+00,
  64. }, { 9.8531161839e-02,-5.6297236492e-02,-1.1421579050e-01,-4.8122536483e-01,-4.0121072432e-01,-7.4834487567e-01,-6.9170822332e-01,0.0000000000e+00,
  65. }, }, { { 1.8229206611e-04,-7.8997325866e-01,2.5782298908e+00,-5.3629717478e+00,6.5890882172e+00,-5.8012914776e+00,3.0171839130e+00,0.0000000000e+00,
  66. }, { 9.8534230718e-02,-5.6297236492e-02,3.8148618075e-01,-1.0848760410e+00,1.8441165168e+00,-2.4860666655e+00,2.3103384142e+00,0.0000000000e+00,
  67. }, }, { { 1.8229206610e-04,-7.8997325866e-01,-3.8715051001e-01,-2.6192408538e+00,-8.3977994034e-01,-2.8329897913e+00,-4.5306444352e-01,0.0000000000e+00,
  68. }, { 9.8531160936e-02,-5.6297236492e-02,-5.7284484199e-02,-4.3673866734e-01,-1.9564766257e-01,-6.2028156584e-01,-3.4692356122e-01,0.0000000000e+00,
  69. }, },
  70. };
  71. /*! \brief Coefficients for output filter
  72. * Coefficients table, generated by program "mkfilter"
  73. * Format: coef[IDX_BW][IDX_COEF]
  74. * IDX_COEF = 0 => 1/GAIN
  75. * IDX_COEF = 1-6 => Coefficientes y[n]
  76. */
  77. static double coef_out[NBW][8]={
  78. { 1.3868644653e-08,-6.3283665042e-01,4.0895057217e+00,-1.1020074592e+01,1.5850766191e+01,-1.2835109292e+01,5.5477477340e+00,0.0000000000e+00,
  79. }, { 3.1262119724e-03,-7.8390522307e-03,8.5209627801e-02,-4.0804129163e-01,1.1157139955e+00,-1.8767603680e+00,1.8916395224e+00,0.0000000000e+00
  80. },
  81. };
  82. /*! Integer Pass Band demodulator filter */
  83. static inline int ibpdfilter(struct filter_struct * fs, int in)
  84. {
  85. int i,j;
  86. int s;
  87. int64_t s_interim;
  88. /* integer filter */
  89. s = in * fs->icoefs[0];
  90. fs->ixv[(fs->ip + 6) & 7] = s;
  91. s = (fs->ixv[fs->ip] + fs->ixv[(fs->ip + 6) & 7]) +
  92. 6 * (fs->ixv[(fs->ip + 1) & 7] + fs->ixv[(fs->ip + 5) & 7]) +
  93. 15 * (fs->ixv[(fs->ip + 2) & 7] + fs->ixv[(fs->ip + 4) & 7]) +
  94. 20 * fs->ixv[(fs->ip + 3) & 7];
  95. for (i = 1, j = fs->ip; i < 7; i++, j++) {
  96. /* Promote operation to 64 bit to prevent overflow that occurred in 32 bit) */
  97. s_interim = (int64_t)(fs->iyv[j & 7]) *
  98. (int64_t)(fs->icoefs[i]) /
  99. (int64_t)(1024);
  100. s += (int) s_interim;
  101. }
  102. fs->iyv[j & 7] = s;
  103. fs->ip++;
  104. fs->ip &= 7;
  105. return s;
  106. }
  107. /*! Integer Band Pass filter */
  108. static inline int ibpfilter(struct filter_struct * fs, int in)
  109. {
  110. int i, j;
  111. int s;
  112. int64_t s_interim;
  113. /* integer filter */
  114. s = in * fs->icoefs[0] / 256;
  115. fs->ixv[(fs->ip + 6) & 7] = s;
  116. s = (fs->ixv[(fs->ip + 6) & 7] - fs->ixv[fs->ip])
  117. + 3 * (fs->ixv[(fs->ip + 2) & 7] - fs->ixv[(fs->ip + 4) & 7]);
  118. for (i = 1, j = fs->ip; i < 7; i++, j++) {
  119. s_interim = (int64_t)(fs->iyv[j & 7]) *
  120. (int64_t)(fs->icoefs[i]) /
  121. (int64_t)(256);
  122. s += (int) s_interim;
  123. }
  124. fs->iyv[j & 7] = s;
  125. fs->ip++;
  126. fs->ip &= 7;
  127. return s;
  128. }
  129. static inline int idemodulator(fsk_data *fskd, int *retval, int x)
  130. {
  131. int is, im, id;
  132. int ilin2;
  133. is = ibpfilter(&fskd->space_filter, x);
  134. im = ibpfilter(&fskd->mark_filter, x);
  135. ilin2 = ((im * im) - (is * is)) / (256 * 256);
  136. id = ibpdfilter(&fskd->demod_filter, ilin2);
  137. *retval = id;
  138. return 0;
  139. }
  140. static int get_bit_raw(fsk_data *fskd, short *buffer, int *len)
  141. {
  142. /* This function implements a DPLL to synchronize with the bits */
  143. int f;
  144. int ix;
  145. /* PLL coeffs are set up in callerid_new */
  146. for (f = 0;;) {
  147. if (idemodulator(fskd, &ix, IGET_SAMPLE)) return(-1);
  148. if ((ix * fskd->xi0) < 0) { /* Transicion */
  149. if (!f) {
  150. if (fskd->icont < (fskd->pllispb2)) {
  151. fskd->icont += fskd->pllids;
  152. } else {
  153. fskd->icont -= fskd->pllids;
  154. }
  155. f = 1;
  156. }
  157. }
  158. fskd->xi0 = ix;
  159. fskd->icont += 32;
  160. if (fskd->icont > fskd->pllispb) {
  161. fskd->icont -= fskd->pllispb;
  162. break;
  163. }
  164. }
  165. f = (ix > 0) ? 0x80 : 0;
  166. return f;
  167. }
  168. int fskmodem_init(fsk_data *fskd)
  169. {
  170. int i;
  171. fskd->space_filter.ip = 0;
  172. fskd->mark_filter.ip = 0;
  173. fskd->demod_filter.ip = 0;
  174. for ( i = 0 ; i < 7 ; i++ ) {
  175. fskd->space_filter.icoefs[i] =
  176. coef_in[fskd->f_space_idx][fskd->bw][i] * 256;
  177. fskd->space_filter.ixv[i] = 0;;
  178. fskd->space_filter.iyv[i] = 0;;
  179. fskd->mark_filter.icoefs[i] =
  180. coef_in[fskd->f_mark_idx][fskd->bw][i] * 256;
  181. fskd->mark_filter.ixv[i] = 0;;
  182. fskd->mark_filter.iyv[i] = 0;;
  183. fskd->demod_filter.icoefs[i] =
  184. coef_out[fskd->bw][i] * 1024;
  185. fskd->demod_filter.ixv[i] = 0;;
  186. fskd->demod_filter.iyv[i] = 0;;
  187. }
  188. return 0;
  189. }
  190. int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte)
  191. {
  192. int a;
  193. int i, j, n1, r;
  194. int samples = 0;
  195. int olen;
  196. int beginlen = *len;
  197. int beginlenx;
  198. switch (fskd->state) {
  199. /* Pick up where we left off */
  200. case STATE_SEARCH_STARTBIT2:
  201. goto search_startbit2;
  202. case STATE_SEARCH_STARTBIT3:
  203. goto search_startbit3;
  204. case STATE_GET_BYTE:
  205. goto getbyte;
  206. }
  207. /* We await for start bit */
  208. do {
  209. /* this was jesus's nice, reasonable, working (at least with RTTY) code
  210. to look for the beginning of the start bit. Unfortunately, since TTY/TDD's
  211. just start sending a start bit with nothing preceding it at the beginning
  212. of a transmission (what a LOSING design), we cant do it this elegantly */
  213. /* NOT USED
  214. if (demodulator(zap,&x1))
  215. return -1;
  216. for(;;) {
  217. if (demodulator(zap,&x2))
  218. return -1;
  219. if (x1>0 && x2<0) break;
  220. x1=x2;
  221. }
  222. */
  223. /* this is now the imprecise, losing, but functional code to detect the
  224. beginning of a start bit in the TDD sceanario. It just looks for sufficient
  225. level to maybe, perhaps, guess, maybe that its maybe the beginning of
  226. a start bit, perhaps. This whole thing stinks! */
  227. beginlenx = beginlen; /* just to avoid unused war warnings */
  228. if (idemodulator(fskd, &fskd->xi1, IGET_SAMPLE))
  229. return -1;
  230. samples++;
  231. for(;;) {
  232. search_startbit2:
  233. if (*len <= 0) {
  234. fskd->state = STATE_SEARCH_STARTBIT2;
  235. return 0;
  236. }
  237. samples++;
  238. if (idemodulator(fskd, &fskd->xi2, IGET_SAMPLE))
  239. return -1;
  240. #if 0
  241. printf("xi2 = %d ", fskd->xi2);
  242. #endif
  243. if (fskd->xi2 < 512) {
  244. break;
  245. }
  246. }
  247. search_startbit3:
  248. /* We await for 0.5 bits before using DPLL */
  249. i = fskd->ispb / 2;
  250. if (*len < i) {
  251. fskd->state = STATE_SEARCH_STARTBIT3;
  252. return 0;
  253. }
  254. for (; i > 0; i--) {
  255. if (idemodulator(fskd, &fskd->xi1, IGET_SAMPLE))
  256. return(-1);
  257. #if 0
  258. printf("xi1 = %d ", fskd->xi1);
  259. #endif
  260. samples++;
  261. }
  262. /* x1 must be negative (start bit confirmation) */
  263. } while (fskd->xi1 > 0);
  264. fskd->state = STATE_GET_BYTE;
  265. getbyte:
  266. /* Need at least 80 samples (for 1200) or
  267. 1320 (for 45.5) to be sure we'll have a byte */
  268. if (fskd->nbit < 8) {
  269. if (*len < 1320)
  270. return 0;
  271. } else {
  272. if (*len < 80)
  273. return 0;
  274. }
  275. /* Now we read the data bits */
  276. j = fskd->nbit;
  277. for (a = n1 = 0; j; j--) {
  278. olen = *len;
  279. i = get_bit_raw(fskd, buffer, len);
  280. buffer += (olen - *len);
  281. if (i == -1)
  282. return -1;
  283. if (i)
  284. n1++;
  285. a >>= 1;
  286. a |= i;
  287. }
  288. j = 8 - fskd->nbit;
  289. a >>= j;
  290. /* We read parity bit (if exists) and check parity */
  291. if (fskd->parity) {
  292. olen = *len;
  293. i = get_bit_raw(fskd, buffer, len);
  294. buffer += (olen - *len);
  295. if (i == -1)
  296. return -1;
  297. if (i)
  298. n1++;
  299. if (fskd->parity == 1) { /* parity=1 (even) */
  300. if (n1 & 1)
  301. a |= 0x100; /* error */
  302. } else { /* parity=2 (odd) */
  303. if (!(n1 & 1))
  304. a |= 0x100; /* error */
  305. }
  306. }
  307. /* We read STOP bits. All of them must be 1 */
  308. for (j = fskd->instop; j; j--) {
  309. r = get_bit_raw(fskd, buffer, len);
  310. if (r == -1)
  311. return -1;
  312. if (!r)
  313. a |= 0x200;
  314. }
  315. /* And finally we return
  316. * Bit 8 : Parity error
  317. * Bit 9 : Framming error
  318. */
  319. *outbyte = a;
  320. fskd->state = STATE_SEARCH_STARTBIT;
  321. return 1;
  322. }