fec_code.c
上传用户:csczyc
上传日期:2021-02-19
资源大小:1051k
文件大小:14k
源码类别:

语音压缩

开发平台:

C/C++

  1. /*
  2.     Name: fec_code.c, fec_decode.c
  3.     Description: Encode/decode FEC (Hamming codes) on selected MELP parameters
  4.     Inputs:
  5.       MELP parameter structure
  6.     Outputs: 
  7.       updated MELP parameter structure
  8.     Returns: void
  9.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  10. */
  11. #include <stdio.h>
  12. #include "typedefs.h"
  13. #include "melp.h"
  14. /* Prototypes */
  15. Shortword binprod_int(Shortword *x, Shortword *y, Shortword n);
  16. Shortword *vgetbits(Shortword *y, Shortword x, Shortword p, Shortword n);
  17. Shortword vsetbits(Shortword x, Shortword p, Shortword n, Shortword *y);
  18. void sbc_enc(Shortword x[], Shortword n, Shortword k, Shortword *pmat);
  19. Shortword sbc_dec(Shortword x[], Shortword n, Shortword k, Shortword *pmat, 
  20.   Shortword syntab[]);
  21. Shortword sbc_syn(Shortword x[], Shortword n, Shortword k, Shortword *pmat);
  22. /* Macros */
  23. #define null_function() exit(1)
  24. /* Set vector to scalar value. */
  25. #define V_SET(x,sc,n) if (1)
  26. {Shortword u__i;
  27.      for(u__i=0; u__i < (n); u__i++)
  28.      *((x)+u__i) = (sc);
  29. } else null_function()
  30. /* Compiler constants */
  31. #define UV_PIND 0    /* Unvoiced pitch index */
  32. #define INVAL_PIND 1 /* Invalid pitch index  */
  33. #define BEP_CORR -1   /* "Correct" bit error position */
  34. #define BEP_UNCORR -2 /* "Uncorrectable" bit error position */
  35. extern Shortword pitch_enc[PIT_QLEV+1]; /* Pitch index encoding table */
  36. extern Shortword pmat74[3][4];  /* (7,4) Hamming code parity matrix */
  37. extern Shortword syntab74[8];   /* (7,4) Hamming code syndrome->bep table */
  38. extern Shortword pmat84[4][4];  /* (8,4) Hamming code parity matrix */
  39. extern Shortword syntab84[16];  /* (8,4) Hamming code syndrome->bep table */
  40. static Shortword codewd74[7];
  41. static Shortword codewd84[8];
  42. void fec_code(struct melp_param *par)
  43. {
  44.     /* Increment pitch index to allow for unvoiced pitch code */
  45.     par->pitch_index++; 
  46. /*
  47. ** Unvoiced case - use spare parameter bits for error protection.
  48. */
  49.     if (par->uv_flag)
  50.     {
  51. /* Set pitch index to unvoiced value */
  52. par->pitch_index = UV_PIND;
  53. /*
  54. ** Code 4 MSB of first vq stage index using (8,4) Hamming code; parity bits in
  55. ** bpvc index.
  56. */
  57. vgetbits(codewd84,par->msvq_index[0],6,4);
  58. sbc_enc(codewd84,8,4,&pmat84[0][0]);
  59. par->bpvc_index=vsetbits(par->bpvc_index,3,4,&codewd84[4]);
  60. /*
  61. ** Code 3 LSB of first vq stage index using (7,4) Hamming code; parity bits
  62. ** in 3 MSB of fsvq index.
  63. */
  64. vgetbits(codewd74,par->msvq_index[0],2,3);
  65. codewd74[3] = 0;
  66. sbc_enc(codewd74,7,4,&pmat74[0][0]);
  67. par->fsvq_index[0]=vsetbits(par->fsvq_index[0],7,3,&codewd74[4]);
  68. /*
  69. ** Code 4 MSB of second gain index using (7,4) Hamming code; parity bits in
  70. ** next 3 MSB of fsvq index.
  71. */
  72. vgetbits(codewd74,par->gain_index[1],4,4);
  73. sbc_enc(codewd74,7,4,&pmat74[0][0]);
  74. par->fsvq_index[0]=vsetbits(par->fsvq_index[0],4,3,&codewd74[4]);
  75. /*
  76. ** Code LSB of second gain index, first gain index using (7,4) Hamming code;
  77. ** parity bits in 2 LSB of fsvq index, jitter index bit.
  78. */
  79. vgetbits(codewd74,par->gain_index[1],0,1);
  80. vgetbits(&codewd74[1],par->gain_index[0],2,3);
  81. sbc_enc(codewd74,7,4,&pmat74[0][0]);
  82. par->fsvq_index[0]=vsetbits(par->fsvq_index[0],1,2,&codewd74[4]);
  83. par->jit_index=vsetbits(par->jit_index,0,1,&codewd74[6]);
  84.     }
  85.     /* Encode pitch index */
  86.     par->pitch_index = pitch_enc[par->pitch_index];
  87. } /* fec_code */
  88. Shortword fec_decode(struct melp_param *par,Shortword erase)
  89. {
  90.     extern Shortword pitch_dec[1<<PIT_BITS]; /* Pitch index decoding table */
  91.     Shortword berr_pos;
  92.     /* Decode pitch index */
  93.     par->pitch_index = pitch_dec[par->pitch_index];
  94. /*
  95. ** Set unvoiced flag for pitch index of UV_PIND; set erase flag for invalid
  96. ** pitch index INVAL_PIND.  Otherwise, convert pitch index into quantization
  97. ** level.
  98. */
  99.     if (!(par->uv_flag = par->pitch_index == UV_PIND) &&
  100. !(erase |= par->pitch_index == INVAL_PIND))
  101. par->pitch_index-=2; /* Subtract to acct. for reserved pitch codes.*/
  102.     if (par->uv_flag && !erase)
  103. /*
  104. ** Unvoiced case - use spare parameter bits for error control coding.
  105. */
  106.     {
  107. /*
  108. ** Decode 4 MSB of first vq stage index using (8,4) Hamming code; parity bits
  109. ** in bpvc index.  Set bpvc index to zero.
  110. */
  111. vgetbits(codewd84,par->msvq_index[0],6,4);
  112. vgetbits(&codewd84[4],par->bpvc_index,3,4);
  113. berr_pos=sbc_dec(codewd84,8,4,&pmat84[0][0],syntab84);
  114. erase |= berr_pos == BEP_UNCORR;
  115. par->msvq_index[0]=vsetbits(par->msvq_index[0],6,4,codewd84);
  116. par->bpvc_index = 0;
  117. /* Perform remaining decoding only if no frame repeat flagged. */
  118. if (!erase)
  119. {
  120. /*
  121. ** Decode 3 LSB of first vq stage index using (7,4) Hamming code; parity bits
  122. ** in 3 MSB of fsvq index.
  123. */
  124.     vgetbits(codewd74,par->msvq_index[0],2,3);
  125.     codewd74[3] = 0;
  126.     vgetbits(&codewd74[4],par->fsvq_index[0],7,3);
  127.     berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74);
  128.     par->msvq_index[0]=vsetbits(par->msvq_index[0],2,3,codewd74);
  129. /*
  130. ** Decode 4 MSB of second gain index using (7,4) Hamming code; parity bits in
  131. ** next 3 MSB of fsvq index.
  132. */
  133.     vgetbits(codewd74,par->gain_index[1],4,4);
  134.     vgetbits(&codewd74[4],par->fsvq_index[0],4,3);
  135.     berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74);
  136.     par->gain_index[1]=vsetbits(par->gain_index[1],4,4,codewd74);
  137. /*
  138. ** Decode LSB of second gain index, first gain index using (7,4) Hamming code;
  139. ** parity bits in 2 LSB of fsvq index, jitter index bit.  Set
  140. ** jitter index bits to one.
  141. */
  142.     vgetbits(codewd74,par->gain_index[1],0,1);
  143.     vgetbits(&codewd74[1],par->gain_index[0],2,3);
  144.     vgetbits(&codewd74[4],par->fsvq_index[0],1,2);
  145.     vgetbits(&codewd74[6],par->jit_index,0,1);
  146.     berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74);
  147.     par->gain_index[1]=vsetbits(par->gain_index[1],0,1,codewd74);
  148.     par->gain_index[0]=vsetbits(par->gain_index[0],2,3,&codewd74[1]);
  149.     par->jit_index = 1;
  150. }
  151.     } /* if (par->uv_flag && !erase) */
  152.     return(erase);
  153. } /* fec_decode */
  154. /*
  155.      binprod returns a
  156.      bitwise modulo-2 inner product between x and y.
  157. */
  158. Shortword binprod_int(Shortword *x, Shortword *y, Shortword n)
  159. {
  160.     Shortword val=(Shortword) 0;
  161.     register Shortword i;
  162.     
  163.     for (i=0; i<n; i++)
  164. val ^= *x++ & *y++;
  165.     
  166.     return(val);
  167. }
  168. /*
  169.      vgetbits extracts an n-bit pattern beginning at bit position p from an
  170.      int, and returns a bit vector containing the pattern.  Conversely,
  171.      vsetbits takes a length n bit vector and sets the bit pattern in an
  172.      integer.
  173. */
  174. Shortword *vgetbits(Shortword *y, Shortword x, Shortword p, Shortword n)
  175. {
  176.     Shortword lsb=0x1; /* least significant bit mask */
  177.     Shortword *retval=y;
  178.     if (n < 0 || p < n-1)
  179. return(NULL);
  180.     
  181.     for (y+=n-1,x>>=p-n+1; y>=retval; y--,x>>=1)
  182. *y = x & lsb;
  183.     return(retval);
  184. }
  185. Shortword vsetbits(Shortword x, Shortword p, Shortword n, Shortword *y)
  186. {
  187.     register Shortword i,j;
  188.     if (n < 0 || p < n-1)
  189. return(x);
  190.     
  191.     for (i=0,j=p; i<n; i++,j--)
  192.     {
  193. x &= ~(0x1 << j);  /* mask out bit position j */
  194. x |= *(y++) << j;  /* set bit position j to array value */
  195.     }
  196.     return(x);
  197. }
  198. /*
  199.    Name: code_blk - systematic block error control code functions.
  200.    Description:
  201.      These functions are designed to implement systematic block codes given an
  202.      input vector and a parity matrix.  These codes are characterized by
  203.      leaving the data bits of the protected n-bit block unaltered.  The parity
  204.      matrix used in these functions is a (n-k) x k matrix which generated the
  205.      parity bits for a given input block.
  206.      sbc_enc takes a length n bit vector x, applies parity matrix pmat, and
  207.      writes the parity bits into the last n-k positions of x.
  208.      sbc_dec takes x (after processing by sbc_enc) and corrects x for bit
  209.      errors using a syndrome table lookup.  sbc_dec returns the index of a
  210.      detected bit error in x.  sbc_dec returns -1 if no error is found.
  211.      sbc_syn takes x (after processing by sbc_enc) and computes a syndrome
  212.      index used to look up a bit error position in the syndrome table.
  213. */
  214. void sbc_enc(Shortword x[], Shortword n, Shortword k, Shortword *pmat)
  215. {
  216.     register Shortword i;
  217.     for (i=k; i<n; i++,pmat+=k)
  218. x[i] = binprod_int(x,pmat,k);
  219. }
  220. Shortword sbc_dec(Shortword x[], Shortword n, Shortword k, Shortword *pmat, Shortword syntab[])
  221. {
  222.     Shortword bep=syntab[sbc_syn(x,n,k,pmat)];
  223.     if (bep > -1)
  224. x[bep] ^= 0x1;
  225.     return(bep);
  226. }
  227. Shortword sbc_syn(Shortword x[], Shortword n, Shortword k, Shortword *pmat)
  228. {
  229.     Shortword retval=0;
  230.     register Shortword i,j;
  231.     for (i=k,j=n-k-1; i<n; i++,j--,pmat+=k)
  232. retval += (x[i] ^ binprod_int(x,pmat,k)) << j;
  233.     return(retval);
  234. }
  235. /*
  236. ** (7,4) Hamming code tables.
  237. */
  238. /* Parity generator matrix. */
  239. Shortword pmat74[3][4] = {{1,1,0,1},{1,0,1,1},{0,1,1,1}};
  240. /* Syndrome table. */
  241. Shortword syntab74[8] = {BEP_CORR,6,5,2,4,1,0,3};
  242. /*
  243. ** (8,4) extended Hamming code tables.
  244. */
  245. /* Parity generator matrix. */
  246. Shortword pmat84[4][4] = {{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0}};
  247. /* Syndrome->error position lookup table. */
  248. Shortword syntab84[16] =
  249. {
  250.     BEP_CORR,    /* 0x0 */
  251.     7,           /* 0x1 */
  252.     6,           /* 0x2 */
  253.     BEP_UNCORR,  /* 0x3 */
  254.     5,           /* 0x4 */
  255.     BEP_UNCORR,  /* 0x5 */
  256.     BEP_UNCORR,  /* 0x6 */
  257.     2,           /* 0x7 */
  258.     4,           /* 0x8 */
  259.     BEP_UNCORR,  /* 0x9 */
  260.     BEP_UNCORR,  /* 0xA */
  261.     1,           /* 0xB */
  262.     BEP_UNCORR,  /* 0xC */
  263.     0,           /* 0xD */
  264.     3,           /* 0xE */
  265.     BEP_UNCORR   /* 0xF */
  266. };
  267. /*
  268. ** Pitch index encoding table.  Reserve Hamming weight 0,1 words for
  269. ** unvoiced pitch value.  Reserve Hamming weight 2 words for invalid (protect
  270. ** against single bit voiced pitch errors.  Assign voiced pitch codes to
  271. ** values having Hamming weight > 2.
  272. */
  273. Shortword pitch_enc[PIT_QLEV+1] = 
  274. {
  275. 0x0, /* UV_PIND */
  276. 0x7, /* 1 (first pitch QL - note offset) */
  277. 0xB, /* 2 */
  278. 0xD, /* 3 */
  279. 0xE, /* 4 */
  280. 0xF, /* 5 */
  281. 0x13, /* 6 */
  282. 0x15, /* 7 */
  283. 0x16, /* 8 */
  284. 0x17, /* 9 */
  285. 0x19, /* 10 */
  286. 0x1A, /* 11 */
  287. 0x1B, /* 12 */
  288. 0x1C, /* 13 */
  289. 0x1D, /* 14 */
  290. 0x1E, /* 15 */
  291. 0x1F, /* 16 */
  292. 0x23, /* 17 */
  293. 0x25, /* 18 */
  294. 0x26, /* 19 */
  295. 0x27, /* 20 */
  296. 0x29, /* 21 */
  297. 0x2A, /* 22 */
  298. 0x2B, /* 23 */
  299. 0x2C, /* 24 */
  300. 0x2D, /* 25 */
  301. 0x2E, /* 26 */
  302. 0x2F, /* 27 */
  303. 0x31, /* 28 */
  304. 0x32, /* 29 */
  305. 0x33, /* 30 */
  306. 0x34, /* 31 */
  307. 0x35, /* 32 */
  308. 0x36, /* 33 */
  309. 0x37, /* 34 */
  310. 0x38, /* 35 */
  311. 0x39, /* 36 */
  312. 0x3A, /* 37 */
  313. 0x3B, /* 38 */
  314. 0x3C, /* 39 */
  315. 0x3D, /* 40 */
  316. 0x3E, /* 41 */
  317. 0x3F, /* 42 */
  318. 0x43, /* 43 */
  319. 0x45, /* 44 */
  320. 0x46, /* 45 */
  321. 0x47, /* 46 */
  322. 0x49, /* 47 */
  323. 0x4A, /* 48 */
  324. 0x4B, /* 49 */
  325. 0x4C, /* 50 */
  326. 0x4D, /* 51 */
  327. 0x4E, /* 52 */
  328. 0x4F, /* 53 */
  329. 0x51, /* 54 */
  330. 0x52, /* 55 */
  331. 0x53, /* 56 */
  332. 0x54, /* 57 */
  333. 0x55, /* 58 */
  334. 0x56, /* 59 */
  335. 0x57, /* 60 */
  336. 0x58, /* 61 */
  337. 0x59, /* 62 */
  338. 0x5A, /* 63 */
  339. 0x5B, /* 64 */
  340. 0x5C, /* 65 */
  341. 0x5D, /* 66 */
  342. 0x5E, /* 67 */
  343. 0x5F, /* 68 */
  344. 0x61, /* 69 */
  345. 0x62, /* 70 */
  346. 0x63, /* 71 */
  347. 0x64, /* 72 */
  348. 0x65, /* 73 */
  349. 0x66, /* 74 */
  350. 0x67, /* 75 */
  351. 0x68, /* 76 */
  352. 0x69, /* 77 */
  353. 0x6A, /* 78 */
  354. 0x6B, /* 79 */
  355. 0x6C, /* 80 */
  356. 0x6D, /* 81 */
  357. 0x6E, /* 82 */
  358. 0x6F, /* 83 */
  359. 0x70, /* 84 */
  360. 0x71, /* 85 */
  361. 0x72, /* 86 */
  362. 0x73, /* 87 */
  363. 0x74, /* 88 */
  364. 0x75, /* 89 */
  365. 0x76, /* 90 */
  366. 0x77, /* 91 */
  367. 0x78, /* 92 */
  368. 0x79, /* 93 */
  369. 0x7A, /* 94 */
  370. 0x7B, /* 95 */
  371. 0x7C, /* 96 */
  372. 0x7D, /* 97 */
  373. 0x7E, /* 98 */
  374. 0x7F /* 99 */
  375. };
  376. /*
  377. ** Pitch index decoding table.  Hamming weight 1 codes map to UV_PIND,
  378. ** allowing for 1-bit error correction of unvoiced marker.  Hamming weight 2
  379. ** codes map to INVAL_PIND, protecting against 1-bit errors in voiced pitches
  380. ** creating false unvoiced condition.
  381. */
  382. Shortword pitch_dec[1<<PIT_BITS] = 
  383. {
  384. UV_PIND, /* 0x0 */
  385. UV_PIND, /* 0x1 */
  386. UV_PIND, /* 0x2 */
  387. INVAL_PIND, /* 0x3 */
  388. UV_PIND, /* 0x4 */
  389. INVAL_PIND, /* 0x5 */
  390. INVAL_PIND, /* 0x6 */
  391. 2, /* 0x7 */
  392. UV_PIND, /* 0x8 */
  393. INVAL_PIND, /* 0x9 */
  394. INVAL_PIND, /* 0xA */
  395. 3, /* 0xB */
  396. INVAL_PIND, /* 0xC */
  397. 4, /* 0xD */
  398. 5, /* 0xE */
  399. 6, /* 0xF */
  400. UV_PIND, /* 0x10 */
  401. INVAL_PIND, /* 0x11 */
  402. INVAL_PIND, /* 0x12 */
  403. 7, /* 0x13 */
  404. INVAL_PIND, /* 0x14 */
  405. 8, /* 0x15 */
  406. 9, /* 0x16 */
  407. 10, /* 0x17 */
  408. INVAL_PIND, /* 0x18 */
  409. 11, /* 0x19 */
  410. 12, /* 0x1A */
  411. 13, /* 0x1B */
  412. 14, /* 0x1C */
  413. 15, /* 0x1D */
  414. 16, /* 0x1E */
  415. 17, /* 0x1F */
  416. UV_PIND, /* 0x20 */
  417. INVAL_PIND, /* 0x21 */
  418. INVAL_PIND, /* 0x22 */
  419. 18, /* 0x23 */
  420. INVAL_PIND, /* 0x24 */
  421. 19, /* 0x25 */
  422. 20, /* 0x26 */
  423. 21, /* 0x27 */
  424. INVAL_PIND, /* 0x28 */
  425. 22, /* 0x29 */
  426. 23, /* 0x2A */
  427. 24, /* 0x2B */
  428. 25, /* 0x2C */
  429. 26, /* 0x2D */
  430. 27, /* 0x2E */
  431. 28, /* 0x2F */
  432. INVAL_PIND, /* 0x30 */
  433. 29, /* 0x31 */
  434. 30, /* 0x32 */
  435. 31, /* 0x33 */
  436. 32, /* 0x34 */
  437. 33, /* 0x35 */
  438. 34, /* 0x36 */
  439. 35, /* 0x37 */
  440. 36, /* 0x38 */
  441. 37, /* 0x39 */
  442. 38, /* 0x3A */
  443. 39, /* 0x3B */
  444. 40, /* 0x3C */
  445. 41, /* 0x3D */
  446. 42, /* 0x3E */
  447. 43, /* 0x3F */
  448. UV_PIND, /* 0x40 */
  449. INVAL_PIND, /* 0x41 */
  450. INVAL_PIND, /* 0x42 */
  451. 44, /* 0x43 */
  452. INVAL_PIND, /* 0x44 */
  453. 45, /* 0x45 */
  454. 46, /* 0x46 */
  455. 47, /* 0x47 */
  456. INVAL_PIND, /* 0x48 */
  457. 48, /* 0x49 */
  458. 49, /* 0x4A */
  459. 50, /* 0x4B */
  460. 51, /* 0x4C */
  461. 52, /* 0x4D */
  462. 53, /* 0x4E */
  463. 54, /* 0x4F */
  464. INVAL_PIND, /* 0x50 */
  465. 55, /* 0x51 */
  466. 56, /* 0x52 */
  467. 57, /* 0x53 */
  468. 58, /* 0x54 */
  469. 59, /* 0x55 */
  470. 60, /* 0x56 */
  471. 61, /* 0x57 */
  472. 62, /* 0x58 */
  473. 63, /* 0x59 */
  474. 64, /* 0x5A */
  475. 65, /* 0x5B */
  476. 66, /* 0x5C */
  477. 67, /* 0x5D */
  478. 68, /* 0x5E */
  479. 69, /* 0x5F */
  480. INVAL_PIND, /* 0x60 */
  481. 70, /* 0x61 */
  482. 71, /* 0x62 */
  483. 72, /* 0x63 */
  484. 73, /* 0x64 */
  485. 74, /* 0x65 */
  486. 75, /* 0x66 */
  487. 76, /* 0x67 */
  488. 77, /* 0x68 */
  489. 78, /* 0x69 */
  490. 79, /* 0x6A */
  491. 80, /* 0x6B */
  492. 81, /* 0x6C */
  493. 82, /* 0x6D */
  494. 83, /* 0x6E */
  495. 84, /* 0x6F */
  496. 85, /* 0x70 */
  497. 86, /* 0x71 */
  498. 87, /* 0x72 */
  499. 88, /* 0x73 */
  500. 89, /* 0x74 */
  501. 90, /* 0x75 */
  502. 91, /* 0x76 */
  503. 92, /* 0x77 */
  504. 93, /* 0x78 */
  505. 94, /* 0x79 */
  506. 95, /* 0x7A */
  507. 96, /* 0x7B */
  508. 97, /* 0x7C */
  509. 98, /* 0x7D */
  510. 99, /* 0x7E */
  511. 100 /* 0x7F */
  512. };