c4_17pf.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /*
  2. ********************************************************************************
  3. *
  4. * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
  5. * R99 Version 3.3.0
  6. * REL-4 Version 4.1.0
  7. *
  8. ********************************************************************************
  9. *
  10. * File : c4_17pf.c
  11. * Purpose : Searches a 17 bit algebraic codebook containing 4 pulses
  12. * in a frame of 40 samples.
  13. *
  14. ********************************************************************************
  15. */
  16. /*
  17. ********************************************************************************
  18. * MODULE INCLUDE FILE AND VERSION ID
  19. ********************************************************************************
  20. */
  21. #include "c4_17pf.h"
  22. const char c4_17pf_id[] = "@(#)$Id $" c4_17pf_h;
  23. /*
  24. ********************************************************************************
  25. * INCLUDE FILES
  26. ********************************************************************************
  27. */
  28. #include "typedef.h"
  29. #include "basic_op.h"
  30. #include "count.h"
  31. #include "inv_sqrt_ex.h"
  32. #include "cnst.h"
  33. #include "cor_h.h"
  34. #include "set_sign.h"
  35. /*
  36. ********************************************************************************
  37. * LOCAL VARIABLES AND TABLES
  38. ********************************************************************************
  39. */
  40. #define NB_PULSE 4
  41. #include "gray.tab"
  42. /*
  43. ********************************************************************************
  44. * DECLARATION OF PROTOTYPES
  45. ********************************************************************************
  46. */
  47. static void search_4i40(
  48. Word16 dn[], /* i : correlation between target and h[] */
  49. Word16 dn2[], /* i : maximum of corr. in each track. */
  50. Word16 rr[][L_CODE],/* i : matrix of autocorrelation */
  51. Word16 codvec[] /* o : algebraic codebook vector */
  52. );
  53. static Word16 build_code(
  54. Word16 codvec[], /* i : algebraic codebook vector */
  55. Word16 dn_sign[], /* i : sign of dn[] */
  56. Word16 cod[], /* o : algebraic (fixed) codebook excitation */
  57. Word16 h[], /* i : impulse response of weighted synthesis filter */
  58. Word16 y[], /* o : filtered fixed codebook excitation */
  59. Word16 sign[] /* o : index of 4 pulses (position+sign+ampl)*4 */
  60. );
  61. /*
  62. ********************************************************************************
  63. * PUBLIC PROGRAM CODE
  64. ********************************************************************************
  65. */
  66. /*************************************************************************
  67. *
  68. * FUNCTION: code_4i40_17bits()
  69. *
  70. * PURPOSE: Searches a 17 bit algebraic codebook containing 4 pulses
  71. * in a frame of 40 samples.
  72. *
  73. * DESCRIPTION:
  74. * The code length is 40, containing 4 nonzero pulses: i0...i3.
  75. * All pulses can have two possible amplitudes: +1 or -1.
  76. * Pulse i0 to i2 can have 8 possible positions, pulse i3 can have
  77. * 2x8=16 positions.
  78. *
  79. * i0 : 0, 5, 10, 15, 20, 25, 30, 35.
  80. * i1 : 1, 6, 11, 16, 21, 26, 31, 36.
  81. * i2 : 2, 7, 12, 17, 22, 27, 32, 37.
  82. * i3 : 3, 8, 13, 18, 23, 28, 33, 38.
  83. * 4, 9, 14, 19, 24, 29, 34, 39.
  84. *
  85. *************************************************************************/
  86. Word16 code_4i40_17bits(
  87. Word16 x[], /* i : target vector */
  88. Word16 h[], /* i : impulse response of weighted synthesis filter */
  89. /* h[-L_subfr..-1] must be set to zero. */
  90. Word16 T0, /* i : Pitch lag */
  91. Word16 pitch_sharp, /* i : Last quantized pitch gain */
  92. Word16 code[], /* o : Innovative codebook */
  93. Word16 y[], /* o : filtered fixed codebook excitation */
  94. Word16 * sign /* o : Signs of 4 pulses */
  95. )
  96. {
  97. Word16 codvec[NB_PULSE];
  98. Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE];
  99. Word16 rr[L_CODE][L_CODE];
  100. Word16 i, index, sharp;
  101. sharp = shl_ex(pitch_sharp, 1);
  102. test ();
  103. if (sub_ex(T0, L_CODE) < 0)
  104. {
  105. for (i = T0; i < L_CODE; i++) {
  106. h[i] = add_ex(h[i], mult_ex(h[i - T0], sharp)); move16 ();
  107. }
  108. }
  109. cor_h_x_ex(h, x, dn, 1);
  110. set_sign(dn, dn_sign, dn2, 4);
  111. cor_h(h, dn_sign, rr);
  112. search_4i40(dn, dn2, rr, codvec);
  113. move16 (); /* function result */
  114. index = build_code(codvec, dn_sign, code, h, y, sign);
  115. /*-----------------------------------------------------------------*
  116. * Compute innovation vector gain. *
  117. * Include fixed-gain pitch contribution into code[]. *
  118. *-----------------------------------------------------------------*/
  119. test ();
  120. if (sub_ex(T0, L_CODE) < 0)
  121. {
  122. for (i = T0; i < L_CODE; i++) {
  123. code[i] = add_ex(code[i], mult_ex(code[i - T0], sharp)); move16 ();
  124. }
  125. }
  126. return index;
  127. }
  128. /*
  129. ********************************************************************************
  130. * PRIVATE PROGRAM CODE
  131. ********************************************************************************
  132. */
  133. /*************************************************************************
  134. *
  135. * FUNCTION search_4i40()
  136. *
  137. * PURPOSE: Search the best codevector; determine positions of the 4 pulses
  138. * in the 40-sample frame.
  139. *
  140. *************************************************************************/
  141. #define _1_2 (Word16)(32768L/2)
  142. #define _1_4 (Word16)(32768L/4)
  143. #define _1_8 (Word16)(32768L/8)
  144. #define _1_16 (Word16)(32768L/16)
  145. static void search_4i40(
  146. Word16 dn[], /* i : correlation between target and h[] */
  147. Word16 dn2[], /* i : maximum of corr. in each track. */
  148. Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
  149. Word16 codvec[] /* o : algebraic codebook vector */
  150. )
  151. {
  152. Word16 i0, i1, i2, i3;
  153. Word16 ix = 0; /* initialization only needed to keep gcc silent */
  154. Word16 ps = 0; /* initialization only needed to keep gcc silent */
  155. Word16 i, pos, track, ipos[NB_PULSE];
  156. Word16 psk, ps0, ps1, sq, sq1;
  157. Word16 alpk, alp, alp_16;
  158. Word32 s, alp0, alp1;
  159. /* Default value */
  160. psk = -1; move16 ();
  161. alpk = 1; move16 ();
  162. for (i = 0; i < NB_PULSE; i++)
  163. {
  164. codvec[i] = i; move16 ();
  165. }
  166. for (track = 3; track < 5; track++) {
  167. /* fix starting position */
  168. ipos[0] = 0; move16 ();
  169. ipos[1] = 1; move16 ();
  170. ipos[2] = 2; move16 ();
  171. ipos[3] = track; move16 ();
  172. /*------------------------------------------------------------------*
  173. * main loop: try 4 tracks. *
  174. *------------------------------------------------------------------*/
  175. for (i = 0; i < NB_PULSE; i++)
  176. {
  177. /*----------------------------------------------------------------*
  178. * i0 loop: try 4 positions (use position with max of corr.). *
  179. *----------------------------------------------------------------*/
  180. move16 (); /* account for ptr. init. (rr[io]) */
  181. for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
  182. {
  183. test (); move16 ();
  184. if (dn2[i0] >= 0)
  185. {
  186. ps0 = dn[i0]; move16 ();
  187. alp0 = L_mult_ex(rr[i0][i0], _1_4);
  188. /*----------------------------------------------------------------*
  189. * i1 loop: 8 positions. *
  190. *----------------------------------------------------------------*/
  191. sq = -1; move16 ();
  192. alp = 1; move16 ();
  193. ps = 0; move16 ();
  194. ix = ipos[1]; move16 ();
  195. /* initialize 4 index for next loop. */
  196. /*-------------------------------------------------------------------*
  197. * These index have low complexity address computation because *
  198. * they are, in fact, pointers with fixed increment. For example, *
  199. * "rr[i0][i3]" is a pointer initialized to "&rr[i0][ipos[3]]" *
  200. * and incremented by "STEP". *
  201. *-------------------------------------------------------------------*/
  202. move16 (); /* account for ptr. init. (rr[i1]) */
  203. move16 (); /* account for ptr. init. (dn[i1]) */
  204. move16 (); /* account for ptr. init. (rr[io]) */
  205. for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP)
  206. {
  207. ps1 = add_ex(ps0, dn[i1]); /* idx increment = STEP */
  208. /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
  209. alp1 = L_mac_ex(alp0, rr[i1][i1], _1_4); /* idx incr = STEP */
  210. alp1 = L_mac_ex(alp1, rr[i0][i1], _1_2); /* idx incr = STEP */
  211. sq1 = mult_ex(ps1, ps1);
  212. alp_16 = round_ex(alp1);
  213. s = L_msu_ex(L_mult_ex(alp, sq1), sq, alp_16);
  214. test ();
  215. if (s > 0)
  216. {
  217. sq = sq1; move16 ();
  218. ps = ps1; move16 ();
  219. alp = alp_16; move16 ();
  220. ix = i1; move16 ();
  221. }
  222. }
  223. i1 = ix; move16 ();
  224. /*----------------------------------------------------------------*
  225. * i2 loop: 8 positions. *
  226. *----------------------------------------------------------------*/
  227. ps0 = ps; move16 ();
  228. alp0 = L_mult_ex(alp, _1_4);
  229. sq = -1; move16 ();
  230. alp = 1; move16 ();
  231. ps = 0; move16 ();
  232. ix = ipos[2]; move16 ();
  233. /* initialize 4 index for next loop (see i1 loop) */
  234. move16 (); /* account for ptr. init. (rr[i2]) */
  235. move16 (); /* account for ptr. init. (rr[i1]) */
  236. move16 (); /* account for ptr. init. (dn[i2]) */
  237. move16 (); /* account for ptr. init. (rr[io]) */
  238. for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP)
  239. {
  240. ps1 = add_ex(ps0, dn[i2]); /* index increment = STEP */
  241. /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
  242. alp1 = L_mac_ex(alp0, rr[i2][i2], _1_16); /* idx incr = STEP */
  243. alp1 = L_mac_ex(alp1, rr[i1][i2], _1_8); /* idx incr = STEP */
  244. alp1 = L_mac_ex(alp1, rr[i0][i2], _1_8); /* idx incr = STEP */
  245. sq1 = mult_ex(ps1, ps1);
  246. alp_16 = round_ex(alp1);
  247. s = L_msu_ex(L_mult_ex(alp, sq1), sq, alp_16);
  248. test ();
  249. if (s > 0)
  250. {
  251. sq = sq1; move16 ();
  252. ps = ps1; move16 ();
  253. alp = alp_16; move16 ();
  254. ix = i2; move16 ();
  255. }
  256. }
  257. i2 = ix; move16 ();
  258. /*----------------------------------------------------------------*
  259. * i3 loop: 8 positions. *
  260. *----------------------------------------------------------------*/
  261. ps0 = ps; move16 ();
  262. alp0 = L_deposit_h_ex(alp);
  263. sq = -1; move16 ();
  264. alp = 1; move16 ();
  265. ps = 0; move16 ();
  266. ix = ipos[3]; move16 ();
  267. /* initialize 5 index for next loop (see i1 loop) */
  268. move16 (); /* account for ptr. init. (rr[i3]) */
  269. move16 (); /* account for ptr. init. (rr[i2]) */
  270. move16 (); /* account for ptr. init. (rr[i1]) */
  271. move16 (); /* account for ptr. init. (dn[i3]) */
  272. move16 (); /* account for ptr. init. (rr[io]) */
  273. for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP)
  274. {
  275. ps1 = add_ex(ps0, dn[i3]); /* index increment = STEP */
  276. /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */
  277. alp1 = L_mac_ex(alp0, rr[i3][i3], _1_16); /* idx incr = STEP */
  278. alp1 = L_mac_ex(alp1, rr[i2][i3], _1_8); /* idx incr = STEP */
  279. alp1 = L_mac_ex(alp1, rr[i1][i3], _1_8); /* idx incr = STEP */
  280. alp1 = L_mac_ex(alp1, rr[i0][i3], _1_8); /* idx incr = STEP */
  281. sq1 = mult_ex(ps1, ps1);
  282. alp_16 = round_ex(alp1);
  283. s = L_msu_ex(L_mult_ex(alp, sq1), sq, alp_16);
  284. test ();
  285. if (s > 0)
  286. {
  287. sq = sq1; move16 ();
  288. ps = ps1; move16 ();
  289. alp = alp_16; move16 ();
  290. ix = i3; move16 ();
  291. }
  292. }
  293. /*----------------------------------------------------------------*
  294. * memorise codevector if this one is better than the last one. *
  295. *----------------------------------------------------------------*/
  296. s = L_msu_ex(L_mult_ex(alpk, sq), psk, alp);
  297. test ();
  298. if (s > 0)
  299. {
  300. psk = sq; move16 ();
  301. alpk = alp; move16 ();
  302. codvec[0] = i0; move16 ();
  303. codvec[1] = i1; move16 ();
  304. codvec[2] = i2; move16 ();
  305. codvec[3] = ix; move16 ();
  306. }
  307. }
  308. }
  309. /*----------------------------------------------------------------*
  310. * Cyclic permutation of i0,i1,i2 and i3. *
  311. *----------------------------------------------------------------*/
  312. pos = ipos[3]; move16 ();
  313. ipos[3] = ipos[2]; move16 ();
  314. ipos[2] = ipos[1]; move16 ();
  315. ipos[1] = ipos[0]; move16 ();
  316. ipos[0] = pos; move16 ();
  317. }
  318. }
  319. return;
  320. }
  321. /*************************************************************************
  322. *
  323. * FUNCTION: build_code()
  324. *
  325. * PURPOSE: Builds the codeword, the filtered codeword and index of the
  326. * codevector, based on the signs and positions of 4 pulses.
  327. *
  328. *************************************************************************/
  329. static Word16
  330. build_code(
  331. Word16 codvec[], /* i : position of pulses */
  332. Word16 dn_sign[], /* i : sign of pulses */
  333. Word16 cod[], /* o : innovative code vector */
  334. Word16 h[], /* i : impulse response of weighted synthesis filter */
  335. Word16 y[], /* o : filtered innovative code */
  336. Word16 sign[] /* o : index of 4 pulses (sign+position) */
  337. )
  338. {
  339. Word16 i, j, k, track, index, _sign[NB_PULSE], indx, rsign;
  340. Word16 *p0, *p1, *p2, *p3;
  341. Word32 s;
  342. for (i = 0; i < L_CODE; i++)
  343. {
  344. cod[i] = 0; move16 ();
  345. }
  346. indx = 0; move16 ();
  347. rsign = 0; move16 ();
  348. for (k = 0; k < NB_PULSE; k++)
  349. {
  350. i = codvec[k]; move16 (); /* read pulse position */
  351. j = dn_sign[i]; move16 (); /* read sign */
  352. index = mult_ex(i, 6554); /* index = pos/5 */
  353. /* track = pos%5 */
  354. track = sub_ex(i, extract_l_ex(L_shr_ex(L_mult_ex(index, 5), 1)));
  355. index = gray[index]; move16 ();
  356. test ();
  357. if (sub_ex(track, 1) == 0)
  358. index = shl_ex(index, 3);
  359. else if (sub_ex(track, 2) == 0)
  360. {
  361. test ();
  362. index = shl_ex(index, 6);
  363. }
  364. else if (sub_ex(track, 3) == 0)
  365. {
  366. test ();test ();
  367. index = shl_ex(index, 10);
  368. }
  369. else if (sub_ex(track, 4) == 0)
  370. {
  371. test ();test ();test ();
  372. track = 3; move16 ();
  373. index = add_ex(shl_ex(index, 10), 512);
  374. }
  375. test ();
  376. if (j > 0)
  377. {
  378. cod[i] = 8191; move16 ();
  379. _sign[k] = 32767; move16 ();
  380. rsign = add_ex(rsign, shl_ex(1, track));
  381. } else {
  382. cod[i] = -8192; move16 ();
  383. _sign[k] = (Word16) - 32768L; move16 ();
  384. }
  385. indx = add_ex(indx, index);
  386. }
  387. *sign = rsign; move16 ();
  388. p0 = h - codvec[0]; move16 ();
  389. p1 = h - codvec[1]; move16 ();
  390. p2 = h - codvec[2]; move16 ();
  391. p3 = h - codvec[3]; move16 ();
  392. for (i = 0; i < L_CODE; i++)
  393. {
  394. s = 0; move32 ();
  395. s = L_mac_ex(s, *p0++, _sign[0]);
  396. s = L_mac_ex(s, *p1++, _sign[1]);
  397. s = L_mac_ex(s, *p2++, _sign[2]);
  398. s = L_mac_ex(s, *p3++, _sign[3]);
  399. y[i] = round_ex(s); move16 ();
  400. }
  401. return indx;
  402. }