gain_q.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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 : gain_q.c
  11. * Purpose : Quantazation of gains
  12. *
  13. ********************************************************************************
  14. */
  15. /*
  16. ********************************************************************************
  17. * MODULE INCLUDE FILE AND VERSION ID
  18. ********************************************************************************
  19. */
  20. #include "gain_q.h"
  21. const char gain_q_id[] = "@(#)$Id $" gain_q_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 "count.h"
  32. #include "qua_gain.h"
  33. #include "cnst.h"
  34. #include "mode.h"
  35. #include "g_code.h"
  36. #include "q_gain_c.h"
  37. #include "gc_pred.h"
  38. #include "calc_en.h"
  39. #include "qgain795.h"
  40. #include "qgain475.h"
  41. #include "set_zero.h"
  42. /*
  43. ********************************************************************************
  44. * LOCAL VARIABLES AND TABLES
  45. ********************************************************************************
  46. */
  47. /*
  48. ********************************************************************************
  49. * PUBLIC PROGRAM CODE
  50. ********************************************************************************
  51. */
  52. /*************************************************************************
  53. *
  54. * Function: gainQuant_init
  55. * Purpose: Allocates state memory and initializes state memory
  56. *
  57. **************************************************************************
  58. */
  59. int gainQuant_init (gainQuantState **state)
  60. {
  61. gainQuantState* s;
  62. if (state == (gainQuantState **) NULL){
  63. wfprintf(stderr, "gainQuant_init: invalid parameter\n");
  64. return -1;
  65. }
  66. *state = NULL;
  67. /* allocate memory */
  68. if ((s= (gainQuantState *) wmalloc(sizeof(gainQuantState))) == NULL){
  69. wfprintf(stderr, "gainQuant_init: can not malloc state structure\n");
  70. return -1;
  71. }
  72. s->gain_idx_ptr = NULL;
  73. s->gc_predSt = NULL;
  74. s->gc_predUnqSt = NULL;
  75. s->adaptSt = NULL;
  76. /* Init sub_ex states */
  77. if ( gc_pred_init(&s->gc_predSt)
  78. || gc_pred_init(&s->gc_predUnqSt)
  79. || gain_adapt_init(&s->adaptSt)) {
  80. gainQuant_exit(&s);
  81. return -1;
  82. }
  83. gainQuant_reset(s);
  84. *state = s;
  85. return 0;
  86. }
  87. /*************************************************************************
  88. *
  89. * Function: gainQuant_reset
  90. * Purpose: Initializes state memory to zero
  91. *
  92. **************************************************************************
  93. */
  94. int gainQuant_reset (gainQuantState *state)
  95. {
  96. if (state == (gainQuantState *) NULL){
  97. wfprintf(stderr, "gainQuant_reset: invalid parameter\n");
  98. return -1;
  99. }
  100. state->sf0_exp_gcode0 = 0;
  101. state->sf0_frac_gcode0 = 0;
  102. state->sf0_exp_target_en = 0;
  103. state->sf0_frac_target_en = 0;
  104. Set_zero (state->sf0_exp_coeff, 5);
  105. Set_zero (state->sf0_frac_coeff, 5);
  106. state->gain_idx_ptr = NULL;
  107. gc_pred_reset(state->gc_predSt);
  108. gc_pred_reset(state->gc_predUnqSt);
  109. gain_adapt_reset(state->adaptSt);
  110. return 0;
  111. }
  112. /*************************************************************************
  113. *
  114. * Function: gainQuant_exit
  115. * Purpose: The memory used for state memory is freed
  116. *
  117. **************************************************************************
  118. */
  119. void gainQuant_exit (gainQuantState **state)
  120. {
  121. if (state == NULL || *state == NULL)
  122. return;
  123. gc_pred_exit(&(*state)->gc_predSt);
  124. gc_pred_exit(&(*state)->gc_predUnqSt);
  125. gain_adapt_exit(&(*state)->adaptSt);
  126. /* deallocate memory */
  127. wfree(*state);
  128. *state = NULL;
  129. return;
  130. }
  131. int gainQuant(
  132. gainQuantState *st, /* i/o : State struct */
  133. enum Mode mode, /* i : coder mode */
  134. Word16 res[], /* i : LP residual, Q0 */
  135. Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */
  136. Word16 code[], /* i : CB innovation (unfiltered), Q13 */
  137. /* (unsharpened for MR475) */
  138. Word16 xn[], /* i : Target vector. */
  139. Word16 xn2[], /* i : Target vector. */
  140. Word16 y1[], /* i : Adaptive codebook. */
  141. Word16 Y2[], /* i : Filtered innovative vector. */
  142. Word16 g_coeff[], /* i : Correlations <xn y1> <y1 y1> */
  143. /* Compute in G_pitch(). */
  144. Word16 even_subframe, /* i : even subframe indicator flag */
  145. Word16 gp_limit, /* i : pitch gain limit */
  146. Word16 *sf0_gain_pit, /* o : Pitch gain sf 0. MR475 */
  147. Word16 *sf0_gain_cod, /* o : Code gain sf 0. MR475 */
  148. Word16 *gain_pit, /* i/o : Pitch gain. */
  149. Word16 *gain_cod, /* o : Code gain. */
  150. /* MR475: gain_* unquantized in even */
  151. /* subframes, quantized otherwise */
  152. Word16 **anap /* o : Index of quantization */
  153. )
  154. {
  155. Word16 exp_gcode0;
  156. Word16 frac_gcode0;
  157. Word16 qua_ener_MR122;
  158. Word16 qua_ener;
  159. Word16 frac_coeff[5];
  160. Word16 exp_coeff[5];
  161. Word16 exp_en, frac_en;
  162. Word16 cod_gain_exp, cod_gain_frac;
  163. test ();
  164. if (sub_ex (mode, MR475) == 0)
  165. {
  166. test ();
  167. if (even_subframe != 0)
  168. {
  169. /* save position in output parameter stream and current
  170. state of codebook gain predictor */
  171. st->gain_idx_ptr = (*anap)++;
  172. gc_pred_copy(st->gc_predSt, st->gc_predUnqSt);
  173. /* predict codebook gain (using "unquantized" predictor)*/
  174. /* (note that code[] is unsharpened in MR475) */
  175. gc_pred(st->gc_predUnqSt, mode, code,
  176. &st->sf0_exp_gcode0, &st->sf0_frac_gcode0,
  177. &exp_en, &frac_en);
  178. /* calculate energy coefficients for quantization
  179. and store them in state structure (will be used
  180. in next subframe when real quantizer is run) */
  181. calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff,
  182. st->sf0_frac_coeff, st->sf0_exp_coeff,
  183. &cod_gain_frac, &cod_gain_exp);
  184. /* store optimum codebook gain (Q1) */
  185. *gain_cod = shl_ex (cod_gain_frac, add_ex (cod_gain_exp, 1));
  186. move16 ();
  187. calc_target_energy(xn,
  188. &st->sf0_exp_target_en, &st->sf0_frac_target_en);
  189. /* calculate optimum codebook gain and update
  190. "unquantized" predictor */
  191. MR475_update_unq_pred(st->gc_predUnqSt,
  192. st->sf0_exp_gcode0, st->sf0_frac_gcode0,
  193. cod_gain_exp, cod_gain_frac);
  194. /* the real quantizer is not run here... */
  195. }
  196. else
  197. {
  198. /* predict codebook gain (using "unquantized" predictor) */
  199. /* (note that code[] is unsharpened in MR475) */
  200. gc_pred(st->gc_predUnqSt, mode, code,
  201. &exp_gcode0, &frac_gcode0,
  202. &exp_en, &frac_en);
  203. /* calculate energy coefficients for quantization */
  204. calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff,
  205. frac_coeff, exp_coeff,
  206. &cod_gain_frac, &cod_gain_exp);
  207. calc_target_energy(xn, &exp_en, &frac_en);
  208. /* run real (4-dim) quantizer and update real gain predictor */
  209. *st->gain_idx_ptr = MR475_gain_quant(
  210. st->gc_predSt,
  211. st->sf0_exp_gcode0, st->sf0_frac_gcode0,
  212. st->sf0_exp_coeff, st->sf0_frac_coeff,
  213. st->sf0_exp_target_en, st->sf0_frac_target_en,
  214. code,
  215. exp_gcode0, frac_gcode0,
  216. exp_coeff, frac_coeff,
  217. exp_en, frac_en,
  218. gp_limit,
  219. sf0_gain_pit, sf0_gain_cod,
  220. gain_pit, gain_cod);
  221. }
  222. }
  223. else
  224. {
  225. /*-------------------------------------------------------------------*
  226. * predict codebook gain and quantize *
  227. * (also compute normalized CB innovation energy for MR795) *
  228. *-------------------------------------------------------------------*/
  229. gc_pred(st->gc_predSt, mode, code, &exp_gcode0, &frac_gcode0,
  230. &exp_en, &frac_en);
  231. test ();
  232. if (sub_ex(mode, MR122) == 0)
  233. {
  234. *gain_cod = G_code_ex (xn2, Y2); move16 ();
  235. *(*anap)++ = q_gain_code (mode, exp_gcode0, frac_gcode0,
  236. gain_cod, &qua_ener_MR122, &qua_ener);
  237. move16 ();
  238. }
  239. else
  240. {
  241. /* calculate energy coefficients for quantization */
  242. calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff,
  243. frac_coeff, exp_coeff,
  244. &cod_gain_frac, &cod_gain_exp);
  245. test ();
  246. if (sub_ex (mode, MR795) == 0)
  247. {
  248. MR795_gain_quant(st->adaptSt, res, exc, code,
  249. frac_coeff, exp_coeff,
  250. exp_en, frac_en,
  251. exp_gcode0, frac_gcode0, L_SUBFR,
  252. cod_gain_frac, cod_gain_exp,
  253. gp_limit, gain_pit, gain_cod,
  254. &qua_ener_MR122, &qua_ener,
  255. anap);
  256. }
  257. else
  258. {
  259. *(*anap)++ = Qua_gain(mode,
  260. exp_gcode0, frac_gcode0,
  261. frac_coeff, exp_coeff, gp_limit,
  262. gain_pit, gain_cod,
  263. &qua_ener_MR122, &qua_ener);
  264. move16 ();
  265. }
  266. }
  267. /*------------------------------------------------------------------*
  268. * update table of past quantized energies *
  269. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
  270. * st->past_qua_en(Q10) = 20 * Log10(qua_gain_code) / constant *
  271. * = Log2(qua_gain_code) *
  272. * = qua_ener *
  273. * constant = 20*Log10(2) *
  274. *------------------------------------------------------------------*/
  275. gc_pred_update(st->gc_predSt, qua_ener_MR122, qua_ener);
  276. }
  277. return 0;
  278. }