qgain475.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  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 : qg475.c
  11. * Purpose : Quantization of pitch and codebook gains for MR475.
  12. *
  13. ********************************************************************************
  14. */
  15. /*
  16. ********************************************************************************
  17. * MODULE INCLUDE FILE AND VERSION ID
  18. ********************************************************************************
  19. */
  20. #include "qgain475.h"
  21. const char qgain475_id[] = "@(#)$Id $" qgain475_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 "mac_32.h"
  32. #include "mode.h"
  33. #include "count.h"
  34. #include "cnst.h"
  35. #include "pow2.h"
  36. #include "log2.h"
  37. /*
  38. ********************************************************************************
  39. * LOCAL VARIABLES AND TABLES
  40. ********************************************************************************
  41. */
  42. /* minimum allowed gain code prediction error: 102.887/4096 = 0.0251189 */
  43. #define MIN_QUA_ENER ( -5443) /* Q10 <-> log2 (0.0251189) */
  44. #define MIN_QUA_ENER_MR122 (-32768) /* Q10 <-> 20*log10(0.0251189) */
  45. /* minimum allowed gain code prediction error: 32000/4096 = 7.8125 */
  46. #define MAX_QUA_ENER ( 3037) /* Q10 <-> log2 (7.8125) */
  47. #define MAX_QUA_ENER_MR122 ( 18284) /* Q10 <-> 20*log10(7.8125) */
  48. #include "qgain475.tab"
  49. /*
  50. ********************************************************************************
  51. * PRIVATE PROGRAM CODE
  52. ********************************************************************************
  53. */
  54. static void MR475_quant_store_results(
  55. gc_predState *pred_st, /* i/o: gain predictor state struct */
  56. const Word16 *p, /* i : pointer to selected quantizer table entry */
  57. Word16 gcode0, /* i : predicted CB gain, Q(14 - exp_gcode0) */
  58. Word16 exp_gcode0, /* i : exponent of predicted CB gain, Q0 */
  59. Word16 *gain_pit, /* o : Pitch gain, Q14 */
  60. Word16 *gain_cod /* o : Code gain, Q1 */
  61. )
  62. {
  63. Word16 g_code, exp, frac, tmp;
  64. Word32 L_tmp;
  65. Word16 qua_ener_MR122; /* o : quantized energy error, MR122 version Q10 */
  66. Word16 qua_ener; /* o : quantized energy error, Q10 */
  67. /* Read the quantized gains */
  68. *gain_pit = *p++; move16 ();
  69. g_code = *p++; move16 ();
  70. /*------------------------------------------------------------------*
  71. * calculate final fixed codebook gain: *
  72. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
  73. * *
  74. * gc = gc0 * g *
  75. *------------------------------------------------------------------*/
  76. L_tmp = L_mult_ex(g_code, gcode0);
  77. L_tmp = L_shr_ex(L_tmp, sub_ex(10, exp_gcode0));
  78. *gain_cod = extract_h_ex(L_tmp);
  79. /*------------------------------------------------------------------*
  80. * calculate predictor update values and update gain predictor: *
  81. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
  82. * *
  83. * qua_ener = log2(g) *
  84. * qua_ener_MR122 = 20*log10(g) *
  85. *------------------------------------------------------------------*/
  86. Log2 (L_deposit_l_ex (g_code), &exp, &frac); /* Log2(x Q12) = log2(x) + 12 */
  87. exp = sub_ex(exp, 12);
  88. tmp = shr_r_ex (frac, 5);
  89. qua_ener_MR122 = add_ex (tmp, shl_ex (exp, 10));
  90. L_tmp = Mpy_32_16(exp, frac, 24660); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
  91. qua_ener = round_ex (L_shl_ex (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */
  92. gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
  93. }
  94. /*
  95. ********************************************************************************
  96. * PUBLIC PROGRAM CODE
  97. ********************************************************************************
  98. */
  99. /*************************************************************************
  100. *
  101. * FUNCTION: MR475_update_unq_pred()
  102. *
  103. * PURPOSE: use optimum codebook gain and update "unquantized"
  104. * gain predictor with the (bounded) prediction error
  105. *
  106. *************************************************************************/
  107. void
  108. MR475_update_unq_pred(
  109. gc_predState *pred_st, /* i/o: gain predictor state struct */
  110. Word16 exp_gcode0, /* i : predicted CB gain (exponent MSW), Q0 */
  111. Word16 frac_gcode0, /* i : predicted CB gain (exponent LSW), Q15 */
  112. Word16 cod_gain_exp, /* i : optimum codebook gain (exponent), Q0 */
  113. Word16 cod_gain_frac /* i : optimum codebook gain (fraction), Q15 */
  114. )
  115. {
  116. Word16 tmp, exp, frac;
  117. Word16 qua_ener, qua_ener_MR122;
  118. Word32 L_tmp;
  119. /* calculate prediction error factor (given optimum CB gain gcu):
  120. *
  121. * predErrFact = gcu / gcode0
  122. * (limit to MIN_PRED_ERR_FACT <= predErrFact <= MAX_PRED_ERR_FACT
  123. * -> limit qua_ener*)
  124. *
  125. * calculate prediction error (log):
  126. *
  127. * qua_ener_MR122 = log2(predErrFact)
  128. * qua_ener = 20*log10(predErrFact)
  129. *
  130. */
  131. if (test(), cod_gain_frac <= 0)
  132. {
  133. /* if gcu <= 0 -> predErrFact = 0 < MIN_PRED_ERR_FACT */
  134. /* -> set qua_ener(_MR122) directly */
  135. qua_ener = MIN_QUA_ENER; move16 ();
  136. qua_ener_MR122 = MIN_QUA_ENER_MR122; move16 ();
  137. }
  138. else
  139. {
  140. /* convert gcode0 from DPF to standard fraction/exponent format */
  141. /* with normalized frac, i.e. 16384 <= frac <= 32767 */
  142. /* Note: exponent correction (exp=exp-14) is done after div_s */
  143. frac_gcode0 = extract_l_ex (Pow2 (14, frac_gcode0));
  144. /* make sure cod_gain_frac < frac_gcode0 for div_s */
  145. if (test (), sub_ex(cod_gain_frac, frac_gcode0) >= 0)
  146. {
  147. cod_gain_frac = shr_ex (cod_gain_frac, 1);
  148. cod_gain_exp = add_ex (cod_gain_exp, 1);
  149. }
  150. /*
  151. predErrFact
  152. = gcu / gcode0
  153. = cod_gain_frac/frac_gcode0 * 2^(cod_gain_exp-(exp_gcode0-14))
  154. = div_s (c_g_f, frac_gcode0)*2^-15 * 2^(c_g_e-exp_gcode0+14)
  155. = div_s * 2^(cod_gain_exp-exp_gcode0 - 1)
  156. */
  157. frac = div_s (cod_gain_frac, frac_gcode0);
  158. tmp = sub_ex (sub_ex (cod_gain_exp, exp_gcode0), 1);
  159. Log2 (L_deposit_l_ex (frac), &exp, &frac);
  160. exp = add_ex (exp, tmp);
  161. /* calculate prediction error (log2, Q10) */
  162. qua_ener_MR122 = shr_r_ex (frac, 5);
  163. qua_ener_MR122 = add_ex (qua_ener_MR122, shl_ex (exp, 10));
  164. if (test (), sub_ex(qua_ener_MR122, MIN_QUA_ENER_MR122) < 0)
  165. {
  166. qua_ener = MIN_QUA_ENER; move16 ();
  167. qua_ener_MR122 = MIN_QUA_ENER_MR122; move16 ();
  168. }
  169. else if (test (), sub_ex(qua_ener_MR122, MAX_QUA_ENER_MR122) > 0)
  170. {
  171. qua_ener = MAX_QUA_ENER; move16 ();
  172. qua_ener_MR122 = MAX_QUA_ENER_MR122; move16 ();
  173. }
  174. else
  175. {
  176. /* calculate prediction error (20*log10, Q10) */
  177. L_tmp = Mpy_32_16(exp, frac, 24660);
  178. /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
  179. qua_ener = round_ex (L_shl_ex (L_tmp, 13));
  180. /* Q12 * Q0 = Q13 -> Q26 -> Q10 */
  181. }
  182. }
  183. /* update MA predictor memory */
  184. gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
  185. }
  186. /*************************************************************************
  187. *
  188. * FUNCTION: MR475_gain_quant()
  189. *
  190. * PURPOSE: Quantization of pitch and codebook gains for two subframes
  191. * (using predicted codebook gain)
  192. *
  193. *************************************************************************/
  194. Word16
  195. MR475_gain_quant( /* o : index of quantization. */
  196. gc_predState *pred_st, /* i/o: gain predictor state struct */
  197. /* data from subframe 0 (or 2) */
  198. Word16 sf0_exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
  199. Word16 sf0_frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
  200. Word16 sf0_exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */
  201. Word16 sf0_frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */
  202. /* (frac_coeff and exp_coeff computed in */
  203. /* calc_filt_energies()) */
  204. Word16 sf0_exp_target_en, /* i : exponent of target energy, Q0 */
  205. Word16 sf0_frac_target_en, /* i : fraction of target energy, Q15 */
  206. /* data from subframe 1 (or 3) */
  207. Word16 sf1_code_nosharp[], /* i : innovative codebook vector (L_SUBFR) */
  208. /* (whithout pitch sharpening) */
  209. Word16 sf1_exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
  210. Word16 sf1_frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
  211. Word16 sf1_exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */
  212. Word16 sf1_frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */
  213. /* (frac_coeff and exp_coeff computed in */
  214. /* calc_filt_energies()) */
  215. Word16 sf1_exp_target_en, /* i : exponent of target energy, Q0 */
  216. Word16 sf1_frac_target_en, /* i : fraction of target energy, Q15 */
  217. Word16 gp_limit, /* i : pitch gain limit */
  218. Word16 *sf0_gain_pit, /* o : Pitch gain, Q14 */
  219. Word16 *sf0_gain_cod, /* o : Code gain, Q1 */
  220. Word16 *sf1_gain_pit, /* o : Pitch gain, Q14 */
  221. Word16 *sf1_gain_cod /* o : Code gain, Q1 */
  222. )
  223. {
  224. const Word16 *p;
  225. Word16 i, index = 0;
  226. Word16 tmp;
  227. Word16 exp;
  228. Word16 sf0_gcode0, sf1_gcode0;
  229. Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
  230. Word16 coeff[10], coeff_lo[10], exp_max[10]; /* 0..4: sf0; 5..9: sf1 */
  231. Word32 L_tmp, dist_min;
  232. /*-------------------------------------------------------------------*
  233. * predicted codebook gain *
  234. * ~~~~~~~~~~~~~~~~~~~~~~~ *
  235. * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
  236. * *
  237. * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
  238. *-------------------------------------------------------------------*/
  239. sf0_gcode0 = extract_l_ex(Pow2(14, sf0_frac_gcode0));
  240. sf1_gcode0 = extract_l_ex(Pow2(14, sf1_frac_gcode0));
  241. /*
  242. * For each subframe, the error energy (sum) to be minimized consists
  243. * of five terms, t[0..4].
  244. *
  245. * t[0] = gp^2 * <y1 y1>
  246. * t[1] = -2*gp * <xn y1>
  247. * t[2] = gc^2 * <y2 y2>
  248. * t[3] = -2*gc * <xn y2>
  249. * t[4] = 2*gp*gc * <y1 y2>
  250. *
  251. */
  252. /* sf 0 */
  253. /* determine the scaling exponent for g_code: ec = ec0 - 11 */
  254. exp = sub_ex(sf0_exp_gcode0, 11);
  255. /* calculate exp_max[i] = s[i]-1 */
  256. exp_max[0] = sub_ex(sf0_exp_coeff[0], 13); move16 ();
  257. exp_max[1] = sub_ex(sf0_exp_coeff[1], 14); move16 ();
  258. exp_max[2] = add_ex(sf0_exp_coeff[2], add_ex(15, shl_ex(exp, 1))); move16 ();
  259. exp_max[3] = add_ex(sf0_exp_coeff[3], exp); move16 ();
  260. exp_max[4] = add_ex(sf0_exp_coeff[4], add_ex(1, exp)); move16 ();
  261. /* sf 1 */
  262. /* determine the scaling exponent for g_code: ec = ec0 - 11 */
  263. exp = sub_ex(sf1_exp_gcode0, 11);
  264. /* calculate exp_max[i] = s[i]-1 */
  265. exp_max[5] = sub_ex(sf1_exp_coeff[0], 13); move16 ();
  266. exp_max[6] = sub_ex(sf1_exp_coeff[1], 14); move16 ();
  267. exp_max[7] = add_ex(sf1_exp_coeff[2], add_ex(15, shl_ex(exp, 1))); move16 ();
  268. exp_max[8] = add_ex(sf1_exp_coeff[3], exp); move16 ();
  269. exp_max[9] = add_ex(sf1_exp_coeff[4], add_ex(1, exp)); move16 ();
  270. /*-------------------------------------------------------------------*
  271. * Gain search equalisation: *
  272. * ~~~~~~~~~~~~~~~~~~~~~~~~~ *
  273. * The MSE for the two subframes is weighted differently if there *
  274. * is a big difference in the corresponding target energies *
  275. *-------------------------------------------------------------------*/
  276. /* make the target energy exponents the same by de-normalizing the
  277. fraction of the smaller one. This is necessary to be able to compare
  278. them
  279. */
  280. exp = sf0_exp_target_en - sf1_exp_target_en;
  281. test ();
  282. if (exp > 0)
  283. {
  284. sf1_frac_target_en = shr_ex (sf1_frac_target_en, exp);
  285. }
  286. else
  287. {
  288. sf0_frac_target_en = shl_ex (sf0_frac_target_en, exp);
  289. }
  290. /* assume no change of exponents */
  291. exp = 0; move16 ();
  292. /* test for target energy difference; set exp to +1 or -1 to scale
  293. * up/down coefficients for sf 1
  294. */
  295. tmp = shr_r_ex (sf1_frac_target_en, 1); /* tmp = ceil(0.5*en(sf1)) */
  296. test ();
  297. if (sub_ex (tmp, sf0_frac_target_en) > 0) /* tmp > en(sf0)? */
  298. {
  299. /*
  300. * target_energy(sf1) > 2*target_energy(sf0)
  301. * -> scale up MSE(sf0) by 2 by adding 1 to exponents 0..4
  302. */
  303. exp = 1; move16 ();
  304. }
  305. else
  306. {
  307. tmp = shr_ex (add_ex (sf0_frac_target_en, 3), 2); /* tmp=ceil(0.25*en(sf0)) */
  308. test();
  309. if (sub_ex (tmp, sf1_frac_target_en) > 0) /* tmp > en(sf1)? */
  310. {
  311. /*
  312. * target_energy(sf1) < 0.25*target_energy(sf0)
  313. * -> scale down MSE(sf0) by 0.5 by subtracting 1 from
  314. * coefficients 0..4
  315. */
  316. exp = -1; move16 ();
  317. }
  318. }
  319. for (i = 0; i < 5; i++)
  320. {
  321. exp_max[i] = add_ex (exp_max[i], exp); move16 ();
  322. }
  323. /*-------------------------------------------------------------------*
  324. * Find maximum exponent: *
  325. * ~~~~~~~~~~~~~~~~~~~~~~ *
  326. * *
  327. * For the sum operation, all terms must have the same scaling; *
  328. * that scaling should be low enough to prevent overflow. There- *
  329. * fore, the maximum scale is determined and all coefficients are *
  330. * re-scaled: *
  331. * *
  332. * exp = max(exp_max[i]) + 1; *
  333. * e = exp_max[i]-exp; e <= 0! *
  334. * c[i] = c[i]*2^e *
  335. *-------------------------------------------------------------------*/
  336. exp = exp_max[0]; move16 ();
  337. for (i = 1; i < 10; i++)
  338. {
  339. move16(); test();
  340. if (sub_ex(exp_max[i], exp) > 0)
  341. {
  342. exp = exp_max[i]; move16 ();
  343. }
  344. }
  345. exp = add_ex(exp, 1); /* To avoid overflow */
  346. p = &sf0_frac_coeff[0]; move16 ();
  347. for (i = 0; i < 5; i++) {
  348. tmp = sub_ex(exp, exp_max[i]);
  349. L_tmp = L_deposit_h_ex(*p++);
  350. L_tmp = L_shr_ex(L_tmp, tmp);
  351. L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
  352. }
  353. p = &sf1_frac_coeff[0]; move16 ();
  354. for (; i < 10; i++) {
  355. tmp = sub_ex(exp, exp_max[i]);
  356. L_tmp = L_deposit_h_ex(*p++);
  357. L_tmp = L_shr_ex(L_tmp, tmp);
  358. L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
  359. }
  360. /*-------------------------------------------------------------------*
  361. * Codebook search: *
  362. * ~~~~~~~~~~~~~~~~ *
  363. * *
  364. * For each pair (g_pitch, g_fac) in the table calculate the *
  365. * terms t[0..4] and sum them up; the result is the mean squared *
  366. * error for the quantized gains from the table. The index for the *
  367. * minimum MSE is stored and finally used to retrieve the quantized *
  368. * gains *
  369. *-------------------------------------------------------------------*/
  370. /* start with "infinite" MSE */
  371. dist_min = MAX_32; move32();
  372. p = &table_gain_MR475[0]; move16 ();
  373. for (i = 0; i < MR475_VQ_SIZE; i++)
  374. {
  375. /* subframe 0 (and 2) calculations */
  376. g_pitch = *p++; move16 ();
  377. g_code = *p++; move16 ();
  378. g_code = mult_ex(g_code, sf0_gcode0);
  379. g2_pitch = mult_ex(g_pitch, g_pitch);
  380. g2_code = mult_ex(g_code, g_code);
  381. g_pit_cod = mult_ex(g_code, g_pitch);
  382. L_tmp = Mpy_32_16( coeff[0], coeff_lo[0], g2_pitch);
  383. L_tmp = Mac_32_16(L_tmp, coeff[1], coeff_lo[1], g_pitch);
  384. L_tmp = Mac_32_16(L_tmp, coeff[2], coeff_lo[2], g2_code);
  385. L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3], g_code);
  386. L_tmp = Mac_32_16(L_tmp, coeff[4], coeff_lo[4], g_pit_cod);
  387. tmp = sub_ex (g_pitch, gp_limit);
  388. /* subframe 1 (and 3) calculations */
  389. g_pitch = *p++; move16 ();
  390. g_code = *p++; move16 ();
  391. test (); test (); test ();
  392. if (tmp <= 0 && sub_ex(g_pitch, gp_limit) <= 0)
  393. {
  394. g_code = mult_ex(g_code, sf1_gcode0);
  395. g2_pitch = mult_ex(g_pitch, g_pitch);
  396. g2_code = mult_ex(g_code, g_code);
  397. g_pit_cod = mult_ex(g_code, g_pitch);
  398. L_tmp = Mac_32_16(L_tmp, coeff[5], coeff_lo[5], g2_pitch);
  399. L_tmp = Mac_32_16(L_tmp, coeff[6], coeff_lo[6], g_pitch);
  400. L_tmp = Mac_32_16(L_tmp, coeff[7], coeff_lo[7], g2_code);
  401. L_tmp = Mac_32_16(L_tmp, coeff[8], coeff_lo[8], g_code);
  402. L_tmp = Mac_32_16(L_tmp, coeff[9], coeff_lo[9], g_pit_cod);
  403. /* store table index if MSE for this index is lower
  404. than the minimum MSE seen so far */
  405. test ();
  406. if (L_sub_ex(L_tmp, dist_min) < (Word32) 0)
  407. {
  408. dist_min = L_tmp; move32 ();
  409. index = i; move16 ();
  410. }
  411. }
  412. }
  413. /*------------------------------------------------------------------*
  414. * read quantized gains and update MA predictor memories *
  415. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
  416. *------------------------------------------------------------------*/
  417. /* for subframe 0, the pre-calculated gcode0/exp_gcode0 are the same
  418. as those calculated from the "real" predictor using quantized gains */
  419. tmp = shl_ex(index, 2);
  420. MR475_quant_store_results(pred_st,
  421. &table_gain_MR475[tmp],
  422. sf0_gcode0,
  423. sf0_exp_gcode0,
  424. sf0_gain_pit,
  425. sf0_gain_cod);
  426. /* calculate new predicted gain for subframe 1 (this time using
  427. the real, quantized gains) */
  428. gc_pred(pred_st, MR475, sf1_code_nosharp,
  429. &sf1_exp_gcode0, &sf1_frac_gcode0,
  430. &sf0_exp_gcode0, &sf0_gcode0); /* last two args are dummy */
  431. sf1_gcode0 = extract_l_ex(Pow2(14, sf1_frac_gcode0));
  432. tmp = add_ex (tmp, 2);
  433. MR475_quant_store_results(pred_st,
  434. &table_gain_MR475[tmp],
  435. sf1_gcode0,
  436. sf1_exp_gcode0,
  437. sf1_gain_pit,
  438. sf1_gain_cod);
  439. return index;
  440. }