fec_code.c
上传用户:luckfish
上传日期:2021-12-16
资源大小:77k
文件大小:13k
源码类别:

语音压缩

开发平台:

Visual C++

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