c2_9pf.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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 : c2_9pf.c
  11. * Purpose : Searches a 9 bit algebraic codebook containing
  12. * 2 pulses in a frame of 40 samples.
  13. *
  14. *****************************************************************************
  15. */
  16. /*
  17. *****************************************************************************
  18. * MODULE INCLUDE FILE AND VERSION ID
  19. *****************************************************************************
  20. */
  21. #include "c2_9pf.h"
  22. const char c2_9pf_id[] = "@(#)$Id $" c2_9pf_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 2
  41. #include "c2_9pf.tab"
  42. /*
  43. *****************************************************************************
  44. * DECLARATION OF PROTOTYPES
  45. *****************************************************************************
  46. */
  47. static void search_2i40(
  48. Word16 subNr, /* i : subframe number */
  49. Word16 dn[], /* i : correlation between target and h[] */
  50. Word16 rr[][L_CODE],/* i : matrix of autocorrelation */
  51. Word16 codvec[] /* o : algebraic codebook vector */
  52. );
  53. static Word16 build_code(
  54. Word16 subNr, /* i : subframe number */
  55. Word16 codvec[], /* i : algebraic codebook vector */
  56. Word16 dn_sign[], /* i : sign of dn[] */
  57. Word16 cod[], /* o : algebraic (fixed) codebook excitation */
  58. Word16 h[], /* i : impulse response of weighted synthesis filter */
  59. Word16 y[], /* o : filtered fixed codebook excitation */
  60. Word16 sign[] /* o : sign of 2 pulses */
  61. );
  62. /*
  63. *****************************************************************************
  64. * PUBLIC PROGRAM CODE
  65. *****************************************************************************
  66. */
  67. /*************************************************************************
  68. *
  69. * FUNCTION: code_2i40_9bits()
  70. *
  71. * PURPOSE: Searches a 9 bit algebraic codebook containing 2 pulses
  72. * in a frame of 40 samples.
  73. *
  74. * DESCRIPTION:
  75. * The code length is 40, containing 2 nonzero pulses: i0...i1.
  76. * All pulses can have two possible amplitudes: +1 or -1.
  77. * Pulse i0 can have 8 possible positions, pulse i1 can have
  78. * 8 positions. Also coded is which track pair should be used,
  79. * i.e. first or second pair. Where each pair contains 2 tracks.
  80. *
  81. * First subframe:
  82. * first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
  83. * i1 : 2, 7, 12, 17, 22, 27, 32, 37.
  84. * second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
  85. * i1 : 3, 8, 13, 18, 23, 28, 33, 38.
  86. *
  87. * Second subframe:
  88. * first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
  89. * i1 : 3, 8, 13, 18, 23, 28, 33, 38.
  90. * second i0 : 2, 7, 12, 17, 22, 27, 32, 37.
  91. * i1 : 4, 9, 14, 19, 24, 29, 34, 39.
  92. *
  93. * Third subframe:
  94. * first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
  95. * i1 : 2, 7, 12, 17, 22, 27, 32, 37.
  96. * second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
  97. * i1 : 4, 9, 14, 19, 24, 29, 34, 39.
  98. *
  99. * Fourth subframe:
  100. * first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
  101. * i1 : 3, 8, 13, 18, 23, 28, 33, 38.
  102. * second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
  103. * i1 : 4, 9, 14, 19, 24, 29, 34, 39.
  104. *
  105. *************************************************************************/
  106. Word16 code_2i40_9bits(
  107. Word16 subNr, /* i : subframe number */
  108. Word16 x[], /* i : target vector */
  109. Word16 h[], /* i : impulse response of weighted synthesis filter */
  110. /* h[-L_subfr..-1] must be set to zero. */
  111. Word16 T0, /* i : Pitch lag */
  112. Word16 pitch_sharp, /* i : Last quantized pitch gain */
  113. Word16 code[], /* o : Innovative codebook */
  114. Word16 y[], /* o : filtered fixed codebook excitation */
  115. Word16 * sign /* o : Signs of 2 pulses */
  116. )
  117. {
  118. Word16 codvec[NB_PULSE];
  119. Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE];
  120. Word16 rr[L_CODE][L_CODE];
  121. Word16 i, index, sharp;
  122. sharp = shl_ex(pitch_sharp, 1);
  123. test ();
  124. if (sub_ex(T0, L_CODE) < 0)
  125. for (i = T0; i < L_CODE; i++) {
  126. h[i] = add_ex(h[i], mult_ex(h[i - T0], sharp)); move16 ();
  127. }
  128. cor_h_x_ex(h, x, dn, 1);
  129. set_sign(dn, dn_sign, dn2, 8); /* dn2[] not used in this codebook search */
  130. cor_h(h, dn_sign, rr);
  131. search_2i40(subNr, dn, rr, codvec);
  132. move16 (); /* function result */
  133. index = build_code(subNr, codvec, dn_sign, code, h, y, sign);
  134. /*-----------------------------------------------------------------*
  135. * Compute innovation vector gain. *
  136. * Include fixed-gain pitch contribution into code[]. *
  137. *-----------------------------------------------------------------*/
  138. test ();
  139. if (sub_ex(T0, L_CODE) < 0)
  140. for (i = T0; i < L_CODE; i++) {
  141. code[i] = add_ex(code[i], mult_ex(code[i - T0], sharp)); move16 ();
  142. }
  143. return index;
  144. }
  145. /*
  146. *****************************************************************************
  147. * PRIVATE PROGRAM CODE
  148. *****************************************************************************
  149. */
  150. /*************************************************************************
  151. *
  152. * FUNCTION search_2i40()
  153. *
  154. * PURPOSE: Search the best codevector; determine positions of the 2 pulses
  155. * in the 40-sample frame.
  156. *
  157. *************************************************************************/
  158. #define _1_2 (Word16)(32768L/2)
  159. #define _1_4 (Word16)(32768L/4)
  160. #define _1_8 (Word16)(32768L/8)
  161. #define _1_16 (Word16)(32768L/16)
  162. static void search_2i40(
  163. Word16 subNr, /* i : subframe number */
  164. Word16 dn[], /* i : correlation between target and h[] */
  165. Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
  166. Word16 codvec[] /* o : algebraic codebook vector */
  167. )
  168. {
  169. Word16 i0, i1;
  170. Word16 ix = 0; /* initialization only needed to keep gcc silent */
  171. Word16 track1, ipos[NB_PULSE];
  172. Word16 psk, ps0, ps1, sq, sq1;
  173. Word16 alpk, alp, alp_16;
  174. Word32 s, alp0, alp1;
  175. Word16 i;
  176. psk = -1; move16 ();
  177. alpk = 1; move16 ();
  178. for (i = 0; i < NB_PULSE; i++)
  179. {
  180. codvec[i] = i; move16 ();
  181. }
  182. for (track1 = 0; track1 < 2; track1++) {
  183. /* fix starting position */
  184. ipos[0] = startPos[subNr*2+8*track1]; move16 ();
  185. ipos[1] = startPos[subNr*2+1+8*track1]; move16 ();
  186. /*----------------------------------------------------------------*
  187. * i0 loop: try 8 positions. *
  188. *----------------------------------------------------------------*/
  189. move16 (); /* account for ptr. init. (rr[io]) */
  190. for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) {
  191. ps0 = dn[i0]; move16 ();
  192. alp0 = L_mult_ex(rr[i0][i0], _1_4);
  193. /*----------------------------------------------------------------*
  194. * i1 loop: 8 positions. *
  195. *----------------------------------------------------------------*/
  196. sq = -1; move16 ();
  197. alp = 1; move16 ();
  198. ix = ipos[1]; move16 ();
  199. /*-------------------------------------------------------------------*
  200. * These index have low complexity address computation because *
  201. * they are, in fact, pointers with fixed increment. For example, *
  202. * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" *
  203. * and incremented by "STEP". *
  204. *-------------------------------------------------------------------*/
  205. move16 (); /* account for ptr. init. (rr[i1]) */
  206. move16 (); /* account for ptr. init. (dn[i1]) */
  207. move16 (); /* account for ptr. init. (rr[io]) */
  208. for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) {
  209. ps1 = add_ex(ps0, dn[i1]); /* idx increment = STEP */
  210. /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
  211. alp1 = L_mac_ex(alp0, rr[i1][i1], _1_4); /* idx incr = STEP */
  212. alp1 = L_mac_ex(alp1, rr[i0][i1], _1_2); /* idx incr = STEP */
  213. sq1 = mult_ex(ps1, ps1);
  214. alp_16 = round_ex(alp1);
  215. s = L_msu_ex(L_mult_ex(alp, sq1), sq, alp_16);
  216. test ();
  217. if (s > 0) {
  218. sq = sq1; move16 ();
  219. alp = alp_16; move16 ();
  220. ix = i1; move16 ();
  221. }
  222. }
  223. /*----------------------------------------------------------------*
  224. * memorise codevector if this one is better than the last one. *
  225. *----------------------------------------------------------------*/
  226. s = L_msu_ex(L_mult_ex(alpk, sq), psk, alp);
  227. test ();
  228. if (s > 0) {
  229. psk = sq; move16 ();
  230. alpk = alp; move16 ();
  231. codvec[0] = i0; move16 ();
  232. codvec[1] = ix; move16 ();
  233. }
  234. }
  235. }
  236. return;
  237. }
  238. /*************************************************************************
  239. *
  240. * FUNCTION: build_code()
  241. *
  242. * PURPOSE: Builds the codeword, the filtered codeword and index of the
  243. * codevector, based on the signs and positions of 2 pulses.
  244. *
  245. *************************************************************************/
  246. static Word16 build_code(
  247. Word16 subNr, /* i : subframe number */
  248. Word16 codvec[], /* i : position of pulses */
  249. Word16 dn_sign[], /* i : sign of pulses */
  250. Word16 cod[], /* o : innovative code vector */
  251. Word16 h[], /* i : impulse response of weighted synthesis filter */
  252. Word16 y[], /* o : filtered innovative code */
  253. Word16 sign[] /* o : sign of 2 pulses */
  254. )
  255. {
  256. Word16 i, j, k, track, first, index, _sign[NB_PULSE], indx, rsign;
  257. Word16 *p0, *p1, *pt;
  258. Word32 s;
  259. static Word16 trackTable[4*5] = {
  260. 0, 1, 0, 1, -1, /* subframe 1; track to code; -1 do not code this position */
  261. 0, -1, 1, 0, 1, /* subframe 2 */
  262. 0, 1, 0, -1, 1, /* subframe 3 */
  263. 0, 1, -1, 0, 1};/* subframe 4 */
  264. pt = &trackTable[add_ex(subNr, shl_ex(subNr, 2))];
  265. for (i = 0; i < L_CODE; i++) {
  266. cod[i] = 0; move16 ();
  267. }
  268. indx = 0; move16 ();
  269. rsign = 0; move16 ();
  270. for (k = 0; k < NB_PULSE; k++) {
  271. i = codvec[k]; /* read pulse position */ move16 ();
  272. j = dn_sign[i]; /* read sign */ move16 ();
  273. index = mult_ex(i, 6554); /* index = pos/5 */
  274. /* track = pos%5 */
  275. track = sub_ex(i, extract_l_ex(L_shr_ex(L_mult_ex(index, 5), 1)));
  276. first = pt[track]; move16 ();
  277. test ();
  278. if (first == 0) {
  279. test ();
  280. if (k == 0) {
  281. track = 0; move16 ();
  282. } else {
  283. track = 1; move16 ();
  284. index = shl_ex(index, 3);
  285. }
  286. } else {
  287. test ();
  288. if (k == 0) {
  289. track = 0; move16 ();
  290. index = add_ex(index, 64); /* table bit is MSB */
  291. } else {
  292. track = 1; move16 ();
  293. index = shl_ex(index, 3);
  294. }
  295. }
  296. test ();
  297. if (j > 0) {
  298. cod[i] = 8191; move16 ();
  299. _sign[k] = 32767; move16 ();
  300. rsign = add_ex(rsign, shl_ex(1, track));
  301. } else {
  302. cod[i] = -8192; move16 ();
  303. _sign[k] = (Word16) - 32768L; move16 ();
  304. }
  305. indx = add_ex(indx, index);
  306. }
  307. *sign = rsign; move16 ();
  308. p0 = h - codvec[0]; move16 ();
  309. p1 = h - codvec[1]; move16 ();
  310. for (i = 0; i < L_CODE; i++) {
  311. s = 0; move32 ();
  312. s = L_mac_ex(s, *p0++, _sign[0]);
  313. s = L_mac_ex(s, *p1++, _sign[1]);
  314. y[i] = round_ex(s); move16 ();
  315. }
  316. return indx;
  317. }