fec_code.c
上传用户:cxx_68
上传日期:2021-02-21
资源大小:161k
文件大小:15k
源码类别:

语音压缩

开发平台:

Visual C++

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