fskmodem_int.c 9.9 KB

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