qgain795.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  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 : qgain795.c
  11. * Purpose : pitch and codebook gain quantization for MR795
  12. *
  13. ********************************************************************************
  14. */
  15. /*
  16. ********************************************************************************
  17. * MODULE INCLUDE FILE AND VERSION ID
  18. ********************************************************************************
  19. */
  20. #include "qgain795.h"
  21. const char qgain795_id[] = "@(#)$Id $" qgain795_h;
  22. /*
  23. ********************************************************************************
  24. * INCLUDE FILES
  25. ********************************************************************************
  26. */
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include "typedef.h"
  30. #include "basic_op.h"
  31. #include "oper_32b.h"
  32. #include "count.h"
  33. #include "cnst.h"
  34. #include "log2.h"
  35. #include "pow2.h"
  36. #include "sqrt_l.h"
  37. #include "g_adapt.h"
  38. #include "calc_en.h"
  39. #include "q_gain_p.h"
  40. #include "mac_32.h"
  41. /*
  42. ********************************************************************************
  43. * LOCAL VARIABLES AND TABLES
  44. ********************************************************************************
  45. */
  46. #include "gains.tab"
  47. /*
  48. ********************************************************************************
  49. * LOCAL PROGRAM CODE
  50. ********************************************************************************
  51. */
  52. /*************************************************************************
  53. *
  54. * FUNCTION: MR795_gain_code_quant3
  55. *
  56. * PURPOSE: Pre-quantization of codebook gains, given three possible
  57. * LTP gains (using predicted codebook gain)
  58. *
  59. *************************************************************************/
  60. static void
  61. MR795_gain_code_quant3(
  62. Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
  63. Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */
  64. Word16 g_pitch_cand[], /* i : Pitch gain candidates (3), Q14 */
  65. Word16 g_pitch_cind[], /* i : Pitch gain cand. indices (3), Q0 */
  66. Word16 frac_coeff[], /* i : coefficients (5), Q15 */
  67. Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */
  68. /* coefficients from calc_filt_ener()*/
  69. Word16 *gain_pit, /* o : Pitch gain, Q14 */
  70. Word16 *gain_pit_ind, /* o : Pitch gain index, Q0 */
  71. Word16 *gain_cod, /* o : Code gain, Q1 */
  72. Word16 *gain_cod_ind, /* o : Code gain index, Q0 */
  73. Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
  74. /* (for MR122 MA predictor update) */
  75. Word16 *qua_ener /* o : quantized energy error, Q10 */
  76. /* (for other MA predictor update) */
  77. )
  78. {
  79. const Word16 *p;
  80. Word16 i, j, cod_ind, pit_ind;
  81. Word16 e_max, exp_code;
  82. Word16 g_pitch, g2_pitch, g_code, g2_code_h, g2_code_l;
  83. Word16 g_pit_cod_h, g_pit_cod_l;
  84. Word16 coeff[5], coeff_lo[5];
  85. Word16 exp_max[5];
  86. Word32 L_tmp, L_tmp0, dist_min;
  87. /*
  88. * The error energy (sum) to be minimized consists of five terms, t[0..4].
  89. *
  90. * t[0] = gp^2 * <y1 y1>
  91. * t[1] = -2*gp * <xn y1>
  92. * t[2] = gc^2 * <y2 y2>
  93. * t[3] = -2*gc * <xn y2>
  94. * t[4] = 2*gp*gc * <y1 y2>
  95. *
  96. */
  97. /* determine the scaling exponent for g_code: ec = ec0 - 10 */
  98. exp_code = sub_ex(exp_gcode0, 10);
  99. /* calculate exp_max[i] = s[i]-1 */
  100. exp_max[0] = sub_ex(exp_coeff[0], 13); move16 ();
  101. exp_max[1] = sub_ex(exp_coeff[1], 14); move16 ();
  102. exp_max[2] = add_ex(exp_coeff[2], add_ex(15, shl_ex(exp_code, 1))); move16 ();
  103. exp_max[3] = add_ex(exp_coeff[3], exp_code); move16 ();
  104. exp_max[4] = add_ex(exp_coeff[4], add_ex(exp_code,1)); move16 ();
  105. /*-------------------------------------------------------------------*
  106. * Find maximum exponent: *
  107. * ~~~~~~~~~~~~~~~~~~~~~~ *
  108. * *
  109. * For the sum operation, all terms must have the same scaling; *
  110. * that scaling should be low enough to prevent overflow. There- *
  111. * fore, the maximum scale is determined and all coefficients are *
  112. * re-scaled: *
  113. * *
  114. * e_max = max(exp_max[i]) + 1; *
  115. * e = exp_max[i]-e_max; e <= 0! *
  116. * c[i] = c[i]*2^e *
  117. *-------------------------------------------------------------------*/
  118. e_max = exp_max[0]; move16 ();
  119. for (i = 1; i < 5; i++) /* implemented flattened */
  120. {
  121. move16(); test();
  122. if (sub_ex(exp_max[i], e_max) > 0)
  123. {
  124. e_max = exp_max[i]; move16 ();
  125. }
  126. }
  127. e_max = add_ex(e_max, 1); /* To avoid overflow */
  128. for (i = 0; i < 5; i++) {
  129. j = sub_ex(e_max, exp_max[i]);
  130. L_tmp = L_deposit_h_ex(frac_coeff[i]);
  131. L_tmp = L_shr_ex(L_tmp, j);
  132. L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
  133. }
  134. /*-------------------------------------------------------------------*
  135. * Codebook search: *
  136. * ~~~~~~~~~~~~~~~~ *
  137. * *
  138. * For each of the candiates LTP gains in g_pitch_cand[], the terms *
  139. * t[0..4] are calculated from the values in the table (and the *
  140. * pitch gain candidate) and summed up; the result is the mean *
  141. * squared error for the LPT/CB gain pair. The index for the mini- *
  142. * mum MSE is stored and finally used to retrieve the quantized CB *
  143. * gain *
  144. *-------------------------------------------------------------------*/
  145. /* start with "infinite" MSE */
  146. dist_min = MAX_32; move16 ();
  147. cod_ind = 0; move16 ();
  148. pit_ind = 0; move16 ();
  149. /* loop through LTP gain candidates */
  150. for (j = 0; j < 3; j++)
  151. {
  152. /* pre-calculate terms only dependent on pitch gain */
  153. g_pitch = g_pitch_cand[j]; move16 ();
  154. g2_pitch = mult_ex(g_pitch, g_pitch);
  155. L_tmp0 = Mpy_32_16( coeff[0], coeff_lo[0], g2_pitch);
  156. L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch);
  157. p = &qua_gain_code[0];
  158. for (i = 0; i < NB_QUA_CODE; i++)
  159. {
  160. g_code = *p++; move16 (); /* this is g_fac Q11 */
  161. p++; /* skip log2(g_fac) */
  162. p++; /* skip 20*log10(g_fac) */
  163. g_code = mult_ex(g_code, gcode0);
  164. L_tmp = L_mult_ex (g_code, g_code);
  165. L_Extract (L_tmp, &g2_code_h, &g2_code_l);
  166. L_tmp = L_mult_ex(g_code, g_pitch);
  167. L_Extract (L_tmp, &g_pit_cod_h, &g_pit_cod_l);
  168. L_tmp = Mac_32 (L_tmp0, coeff[2], coeff_lo[2],
  169. g2_code_h, g2_code_l);
  170. L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3],
  171. g_code);
  172. L_tmp = Mac_32 (L_tmp, coeff[4], coeff_lo[4],
  173. g_pit_cod_h, g_pit_cod_l);
  174. /* store table index if MSE for this index is lower
  175. than the minimum MSE seen so far; also store the
  176. pitch gain for this (so far) lowest MSE */
  177. test ();
  178. if (L_sub_ex(L_tmp, dist_min) < (Word32) 0)
  179. {
  180. dist_min = L_tmp; move32 ();
  181. cod_ind = i; move16 ();
  182. pit_ind = j; move16 ();
  183. }
  184. }
  185. }
  186. /*------------------------------------------------------------------*
  187. * read quantized gains and new values for MA predictor memories *
  188. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
  189. *------------------------------------------------------------------*/
  190. /* Read the quantized gains */
  191. p = &qua_gain_code[add_ex (add_ex (cod_ind, cod_ind), cod_ind)]; move16 ();
  192. g_code = *p++; move16();
  193. *qua_ener_MR122 = *p++; move16();
  194. *qua_ener = *p; move16();
  195. /*------------------------------------------------------------------*
  196. * calculate final fixed codebook gain: *
  197. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
  198. * *
  199. * gc = gc0 * g *
  200. *------------------------------------------------------------------*/
  201. L_tmp = L_mult_ex(g_code, gcode0);
  202. L_tmp = L_shr_ex(L_tmp, sub_ex(9, exp_gcode0));
  203. *gain_cod = extract_h_ex(L_tmp);
  204. *gain_cod_ind = cod_ind; move16 ();
  205. *gain_pit = g_pitch_cand[pit_ind]; move16 ();
  206. *gain_pit_ind = g_pitch_cind[pit_ind]; move16 ();
  207. }
  208. /*************************************************************************
  209. *
  210. * FUNCTION: MR795_gain_code_quant_mod
  211. *
  212. * PURPOSE: Modified quantization of the MR795 codebook gain
  213. *
  214. * Uses pre-computed energy coefficients in frac_en[]/exp_en[]
  215. *
  216. * frac_en[0]*2^exp_en[0] = <res res> // LP residual energy
  217. * frac_en[1]*2^exp_en[1] = <exc exc> // LTP residual energy
  218. * frac_en[2]*2^exp_en[2] = <exc code> // LTP/CB innovation dot product
  219. * frac_en[3]*2^exp_en[3] = <code code> // CB innovation energy
  220. *
  221. *************************************************************************/
  222. static Word16
  223. MR795_gain_code_quant_mod( /* o : index of quantization. */
  224. Word16 gain_pit, /* i : pitch gain, Q14 */
  225. Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
  226. Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */
  227. Word16 frac_en[], /* i : energy coefficients (4),
  228. fraction part, Q15 */
  229. Word16 exp_en[], /* i : energy coefficients (4),
  230. eponent part, Q0 */
  231. Word16 alpha, /* i : gain adaptor factor (>0), Q15 */
  232. Word16 gain_cod_unq, /* i : Code gain (unquantized) */
  233. /* (scaling: Q10 - exp_gcode0) */
  234. Word16 *gain_cod, /* i/o: Code gain (pre-/quantized), Q1 */
  235. Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
  236. /* (for MR122 MA predictor update) */
  237. Word16 *qua_ener /* o : quantized energy error, Q10 */
  238. /* (for other MA predictor update) */
  239. )
  240. {
  241. const Word16 *p;
  242. Word16 i, index, tmp;
  243. Word16 one_alpha;
  244. Word16 exp, e_max;
  245. Word16 g2_pitch, g_code;
  246. Word16 g2_code_h, g2_code_l;
  247. Word16 d2_code_h, d2_code_l;
  248. Word16 coeff[5], coeff_lo[5], exp_coeff[5];
  249. Word32 L_tmp, L_t0, L_t1, dist_min;
  250. Word16 gain_code;
  251. /*
  252. Steps in calculation of the error criterion (dist):
  253. ---------------------------------------------------
  254. underlined = constant; alp = FLP value of alpha, alpha = FIP
  255. ----------
  256. ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn;
  257. ------------ ------ -- -----
  258. aExEn= alp * ExEn
  259. = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2
  260. -------------- ------------- ---------
  261. = t[1] + t[2] + t[3]
  262. dist = d1 + d2;
  263. d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4]
  264. ------------------- ---
  265. d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn);
  266. --- ----- --- -----
  267. = alp * (sqrt(ExEn) - sqrt(ResEn))^2
  268. --- -----------
  269. = (sqrt(aExEn) - sqrt(alp*ResEn))^2
  270. ---------------
  271. = (sqrt(aExEn) - t[0] )^2
  272. ----
  273. */
  274. /*
  275. * calculate scalings of the constant terms
  276. */
  277. gain_code = shl_ex (*gain_cod, sub_ex (10, exp_gcode0)); /* Q1 -> Q11 (-ec0) */
  278. g2_pitch = mult_ex (gain_pit, gain_pit); /* Q14 -> Q13 */
  279. /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized */
  280. one_alpha = add_ex (sub_ex (32767, alpha), 1); /* 32768 - alpha */
  281. /* alpha <= 0.5 -> mult_ex. by 2 to keep precision; compensate in exponent */
  282. tmp = extract_h_ex (L_shl_ex (L_mult_ex (alpha, frac_en[1]), 1));
  283. /* directly store in 32 bit variable because no further mult_ex. required */
  284. L_t1 = L_mult_ex (tmp, g2_pitch); move16 ();
  285. exp_coeff[1] = sub_ex (exp_en[1], 15); move16 ();
  286. tmp = extract_h_ex (L_shl_ex (L_mult_ex (alpha, frac_en[2]), 1));
  287. coeff[2] = mult_ex (tmp, gain_pit); move16 ();
  288. exp = sub_ex (exp_gcode0, 10);
  289. exp_coeff[2] = add_ex (exp_en[2], exp); move16 ();
  290. /* alpha <= 0.5 -> mult_ex. by 2 to keep precision; compensate in exponent */
  291. coeff[3] = extract_h_ex (L_shl_ex (L_mult_ex (alpha, frac_en[3]), 1));
  292. exp = sub_ex (shl_ex (exp_gcode0, 1), 7);
  293. exp_coeff[3] = add_ex (exp_en[3], exp); move16 ();
  294. coeff[4] = mult_ex (one_alpha, frac_en[3]); move16 ();
  295. exp_coeff[4] = add_ex (exp_coeff[3], 1); move16 ();
  296. L_tmp = L_mult_ex (alpha, frac_en[0]);
  297. /* sqrt_l returns normalized value and 2*exponent
  298. -> result = val >> (exp/2)
  299. exp_coeff holds 2*exponent for c[0] */
  300. /* directly store in 32 bit variable because no further mult_ex. required */
  301. L_t0 = sqrt_l_exp (L_tmp, &exp); /* normalization included in sqrt_l_exp */
  302. move32 (); /* function result */
  303. exp = add_ex (exp, 47);
  304. exp_coeff[0] = sub_ex (exp_en[0], exp); move16 ();
  305. /*
  306. * Determine the maximum exponent occuring in the distance calculation
  307. * and adjust all fractions accordingly (including a safety margin)
  308. *
  309. */
  310. /* find max(e[1..4],e[0]+31) */
  311. e_max = add_ex (exp_coeff[0], 31);
  312. for (i = 1; i <= 4; i++)
  313. {
  314. test ();
  315. if (sub_ex (exp_coeff[i], e_max) > 0)
  316. {
  317. e_max = exp_coeff[i]; move16 ();
  318. }
  319. }
  320. /* scale c[1] (requires no further multiplication) */
  321. tmp = sub_ex (e_max, exp_coeff[1]);
  322. L_t1 = L_shr_ex(L_t1, tmp);
  323. /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */
  324. for (i = 2; i <= 4; i++)
  325. {
  326. tmp = sub_ex (e_max, exp_coeff[i]);
  327. L_tmp = L_deposit_h_ex(coeff[i]);
  328. L_tmp = L_shr_ex(L_tmp, tmp);
  329. L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
  330. }
  331. /* scale c[0] (requires no further multiplication) */
  332. exp = sub_ex (e_max, 31); /* new exponent */
  333. tmp = sub_ex (exp, exp_coeff[0]);
  334. L_t0 = L_shr_ex (L_t0, shr_ex (tmp, 1));
  335. /* perform correction by 1/sqrt(2) if exponent difference is odd */
  336. test (); logic16 ();
  337. if ((tmp & 0x1) != 0)
  338. {
  339. L_Extract(L_t0, &coeff[0], &coeff_lo[0]);
  340. L_t0 = Mpy_32_16(coeff[0], coeff_lo[0],
  341. 23170); /* 23170 Q15 = 1/sqrt(2)*/
  342. }
  343. /* search the quantizer table for the lowest value
  344. of the search criterion */
  345. dist_min = MAX_32; move32 ();
  346. index = 0; move16 ();
  347. p = &qua_gain_code[0]; move16 ();
  348. for (i = 0; i < NB_QUA_CODE; i++)
  349. {
  350. g_code = *p++; move16 (); /* this is g_fac (Q11) */
  351. p++; /* skip log2(g_fac) */
  352. p++; /* skip 20*log10(g_fac) */
  353. g_code = mult_ex (g_code, gcode0);
  354. /* only continue if gc[i] < 2.0*gc
  355. which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */
  356. test ();
  357. if (sub_ex (g_code, gain_code) >= 0)
  358. break;
  359. L_tmp = L_mult_ex (g_code, g_code);
  360. L_Extract (L_tmp, &g2_code_h, &g2_code_l);
  361. tmp = sub_ex (g_code, gain_cod_unq);
  362. L_tmp = L_mult_ex (tmp, tmp);
  363. L_Extract (L_tmp, &d2_code_h, &d2_code_l);
  364. /* t2, t3, t4 */
  365. L_tmp = Mac_32_16 (L_t1, coeff[2], coeff_lo[2], g_code);
  366. L_tmp = Mac_32(L_tmp, coeff[3], coeff_lo[3], g2_code_h, g2_code_l);
  367. L_tmp = sqrt_l_exp (L_tmp, &exp);
  368. L_tmp = L_shr_ex (L_tmp, shr_ex (exp, 1));
  369. /* d2 */
  370. tmp = round_ex (L_sub_ex (L_tmp, L_t0));
  371. L_tmp = L_mult_ex (tmp, tmp);
  372. /* dist */
  373. L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l);
  374. /* store table index if distance measure for this
  375. index is lower than the minimum seen so far */
  376. test ();
  377. if (L_sub_ex (L_tmp, dist_min) < (Word32) 0)
  378. {
  379. dist_min = L_tmp; move16 ();
  380. index = i; move16 ();
  381. }
  382. }
  383. /*------------------------------------------------------------------*
  384. * read quantized gains and new values for MA predictor memories *
  385. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
  386. *------------------------------------------------------------------*/
  387. /* Read the quantized gains */
  388. p = &qua_gain_code[add_ex (add_ex (index, index), index)]; move16 ();
  389. g_code = *p++; move16();
  390. *qua_ener_MR122 = *p++; move16();
  391. *qua_ener = *p; move16();
  392. /*------------------------------------------------------------------*
  393. * calculate final fixed codebook gain: *
  394. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
  395. * *
  396. * gc = gc0 * g *
  397. *------------------------------------------------------------------*/
  398. L_tmp = L_mult_ex(g_code, gcode0);
  399. L_tmp = L_shr_ex(L_tmp, sub_ex(9, exp_gcode0));
  400. *gain_cod = extract_h_ex(L_tmp);
  401. return index;
  402. }
  403. /*
  404. ********************************************************************************
  405. * PUBLIC PROGRAM CODE
  406. ********************************************************************************
  407. */
  408. /*************************************************************************
  409. *
  410. * FUNCTION: MR795_gain_quant
  411. *
  412. * PURPOSE: pitch and codebook quantization for MR795
  413. *
  414. *************************************************************************/
  415. void
  416. MR795_gain_quant(
  417. GainAdaptState *adapt_st, /* i/o: gain adapter state structure */
  418. Word16 res[], /* i : LP residual, Q0 */
  419. Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */
  420. Word16 code[], /* i : CB innovation (unfiltered), Q13 */
  421. Word16 frac_coeff[], /* i : coefficients (5), Q15 */
  422. Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */
  423. /* coefficients from calc_filt_ener() */
  424. Word16 exp_code_en, /* i : innovation energy (exponent), Q0 */
  425. Word16 frac_code_en, /* i : innovation energy (fraction), Q15 */
  426. Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
  427. Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
  428. Word16 L_subfr, /* i : Subframe length */
  429. Word16 cod_gain_frac, /* i : opt. codebook gain (fraction),Q15 */
  430. Word16 cod_gain_exp, /* i : opt. codebook gain (exponent), Q0 */
  431. Word16 gp_limit, /* i : pitch gain limit */
  432. Word16 *gain_pit, /* i/o: Pitch gain, Q14 */
  433. Word16 *gain_cod, /* o : Code gain, Q1 */
  434. Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
  435. /* (for MR122 MA predictor update) */
  436. Word16 *qua_ener, /* o : quantized energy error, Q10 */
  437. /* (for other MA predictor update) */
  438. Word16 **anap /* o : Index of quantization */
  439. /* (first gain pitch, then code pitch)*/
  440. )
  441. {
  442. Word16 frac_en[4];
  443. Word16 exp_en[4];
  444. Word16 ltpg, alpha, gcode0;
  445. Word16 g_pitch_cand[3]; /* pitch gain candidates Q14 */
  446. Word16 g_pitch_cind[3]; /* pitch gain indices Q0 */
  447. Word16 gain_pit_index;
  448. Word16 gain_cod_index;
  449. Word16 exp;
  450. Word16 gain_cod_unq; /* code gain (unq.) Q(10-exp_gcode0) */
  451. /* get list of candidate quantized pitch gain values
  452. * and corresponding quantization indices
  453. */
  454. gain_pit_index = q_gain_pitch (MR795, gp_limit, gain_pit,
  455. g_pitch_cand, g_pitch_cind);
  456. move16 (); /* function result */
  457. /*-------------------------------------------------------------------*
  458. * predicted codebook gain *
  459. * ~~~~~~~~~~~~~~~~~~~~~~~ *
  460. * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
  461. * *
  462. * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
  463. *-------------------------------------------------------------------*/
  464. gcode0 = extract_l_ex(Pow2(14, frac_gcode0)); /* Q14 */
  465. /* pre-quantization of codebook gain
  466. * (using three pitch gain candidates);
  467. * result: best guess of pitch gain and code gain
  468. */
  469. MR795_gain_code_quant3(
  470. exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind,
  471. frac_coeff, exp_coeff,
  472. gain_pit, &gain_pit_index, gain_cod, &gain_cod_index,
  473. qua_ener_MR122, qua_ener);
  474. /* calculation of energy coefficients and LTP coding gain */
  475. calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr,
  476. frac_en, exp_en, &ltpg);
  477. /* run gain adaptor, calculate alpha factor to balance LTP/CB gain
  478. * (this includes the gain adaptor update)
  479. * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case
  480. */
  481. gain_adapt(adapt_st, ltpg, *gain_cod, &alpha);
  482. /* if this is a very low energy signal (threshold: see
  483. * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer
  484. */
  485. test (); move16 (); test ();
  486. if (frac_en[0] != 0 && alpha > 0)
  487. {
  488. /* innovation energy <cod cod> was already computed in gc_pred() */
  489. /* (this overwrites the LtpResEn which is no longer needed) */
  490. frac_en[3] = frac_code_en; move16 ();
  491. exp_en[3] = exp_code_en; move16 ();
  492. /* store optimum codebook gain in Q(10-exp_gcode0) */
  493. exp = add_ex (sub_ex (cod_gain_exp, exp_gcode0), 10);
  494. gain_cod_unq = shl_ex (cod_gain_frac, exp);
  495. /* run quantization with modified criterion */
  496. gain_cod_index = MR795_gain_code_quant_mod(
  497. *gain_pit, exp_gcode0, gcode0,
  498. frac_en, exp_en, alpha, gain_cod_unq,
  499. gain_cod, qua_ener_MR122, qua_ener); move16 (); /* function result */
  500. }
  501. *(*anap)++ = gain_pit_index; move16 ();
  502. *(*anap)++ = gain_cod_index; move16 ();
  503. }