agc.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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 : agc.c
  11. *
  12. *****************************************************************************
  13. */
  14. /*
  15. *****************************************************************************
  16. * MODULE INCLUDE FILE AND VERSION ID
  17. *****************************************************************************
  18. */
  19. #include "agc.h"
  20. const char agc_id[] = "@(#)$Id $" agc_h;
  21. /*
  22. *****************************************************************************
  23. * INCLUDE FILES
  24. *****************************************************************************
  25. */
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include "typedef.h"
  29. #include "basic_op.h"
  30. #include "count.h"
  31. #include "cnst.h"
  32. #include "inv_sqrt_ex.h"
  33. /*
  34. *****************************************************************************
  35. * LOCAL VARIABLES AND TABLES
  36. *****************************************************************************
  37. */
  38. /*
  39. *****************************************************************************
  40. * LOCAL PROGRAM CODE
  41. *****************************************************************************
  42. */
  43. static Word32 energy_old( /* o : return energy of signal */
  44. Word16 in[], /* i : input signal (length l_trm) */
  45. Word16 l_trm /* i : signal length */
  46. )
  47. {
  48. Word32 s;
  49. Word16 i, temp;
  50. temp = shr_ex (in[0], 2);
  51. s = L_mult_ex (temp, temp);
  52. for (i = 1; i < l_trm; i++)
  53. {
  54. temp = shr_ex (in[i], 2);
  55. s = L_mac_ex (s, temp, temp);
  56. }
  57. return s;
  58. }
  59. static Word32 energy_new( /* o : return energy of signal */
  60. Word16 in[], /* i : input signal (length l_trm) */
  61. Word16 l_trm /* i : signal length */
  62. )
  63. {
  64. Word32 s;
  65. Word16 i;
  66. Flag ov_save;
  67. ov_save = Overflow; move16 (); /* save overflow flag in case energy_old */
  68. /* must be called */
  69. s = L_mult_ex(in[0], in[0]);
  70. for (i = 1; i < l_trm; i++)
  71. {
  72. s = L_mac_ex(s, in[i], in[i]);
  73. }
  74. /* check for overflow */
  75. test ();
  76. if (L_sub_ex (s, MAX_32) == 0L)
  77. {
  78. Overflow = ov_save; move16 (); /* restore overflow flag */
  79. s = energy_old (in, l_trm); move32 (); /* function result */
  80. }
  81. else
  82. {
  83. s = L_shr_ex(s, 4);
  84. }
  85. return s;
  86. }
  87. /*
  88. *****************************************************************************
  89. * PUBLIC PROGRAM CODE
  90. *****************************************************************************
  91. */
  92. /*
  93. **************************************************************************
  94. *
  95. * Function : agc_init
  96. * Purpose : Allocates memory for agc state and initializes
  97. * state memory
  98. *
  99. **************************************************************************
  100. */
  101. int agc_init (agcState **state)
  102. {
  103. agcState* s;
  104. if (state == (agcState **) NULL){
  105. wfprintf(stderr, "agc_init: invalid parameter\n");
  106. return -1;
  107. }
  108. *state = NULL;
  109. /* allocate memory */
  110. if ((s= (agcState *) wmalloc(sizeof(agcState))) == NULL){
  111. wfprintf(stderr, "agc_init: can not malloc state structure\n");
  112. return -1;
  113. }
  114. agc_reset(s);
  115. *state = s;
  116. return 0;
  117. }
  118. /*
  119. **************************************************************************
  120. *
  121. * Function : agc_reset
  122. * Purpose : Reset of agc (i.e. set state memory to 1.0)
  123. *
  124. **************************************************************************
  125. */
  126. int agc_reset (agcState *state)
  127. {
  128. if (state == (agcState *) NULL){
  129. wfprintf(stderr, "agc_reset: invalid parameter\n");
  130. return -1;
  131. }
  132. state->past_gain = 4096; /* initial value of past_gain = 1.0 */
  133. return 0;
  134. }
  135. /*
  136. **************************************************************************
  137. *
  138. * Function : agc_exit
  139. * Purpose : The memory used for state memory is freed
  140. *
  141. **************************************************************************
  142. */
  143. void agc_exit (agcState **state)
  144. {
  145. if (state == NULL || *state == NULL)
  146. return;
  147. /* deallocate memory */
  148. wfree(*state);
  149. *state = NULL;
  150. return;
  151. }
  152. /*
  153. **************************************************************************
  154. *
  155. * Function : agc
  156. * Purpose : Scales the postfilter output on a subframe basis
  157. *
  158. **************************************************************************
  159. */
  160. int agc (
  161. agcState *st, /* i/o : agc state */
  162. Word16 *sig_in, /* i : postfilter input signal (l_trm) */
  163. Word16 *sig_out, /* i/o : postfilter output signal (l_trm) */
  164. Word16 agc_fac, /* i : AGC factor */
  165. Word16 l_trm /* i : subframe size */
  166. )
  167. {
  168. Word16 i, exp;
  169. Word16 gain_in, gain_out, g0, gain;
  170. Word32 s;
  171. /* calculate gain_out with exponent */
  172. s = energy_new(sig_out, l_trm); move32 (); /* function result */
  173. test ();
  174. if (s == 0)
  175. {
  176. st->past_gain = 0; move16 ();
  177. return 0;
  178. }
  179. exp = sub_ex (norm_l_ex (s), 1);
  180. gain_out = round_ex (L_shl_ex (s, exp));
  181. /* calculate gain_in with exponent */
  182. s = energy_new(sig_in, l_trm); move32 (); /* function result */
  183. test ();
  184. if (s == 0)
  185. {
  186. g0 = 0; move16 ();
  187. }
  188. else
  189. {
  190. i = norm_l_ex (s);
  191. gain_in = round_ex (L_shl_ex (s, i));
  192. exp = sub_ex (exp, i);
  193. /*---------------------------------------------------*
  194. * g0 = (1-agc_fac) * sqrt(gain_in/gain_out); *
  195. *---------------------------------------------------*/
  196. s = L_deposit_l_ex (div_s (gain_out, gain_in));
  197. s = L_shl_ex (s, 7); /* s = gain_out / gain_in */
  198. s = L_shr_ex (s, exp); /* add exponent */
  199. s = Inv_sqrt_ex (s); move32 (); /* function result */
  200. i = round_ex (L_shl_ex (s, 9));
  201. /* g0 = i * (1-agc_fac) */
  202. g0 = mult_ex (i, sub_ex (32767, agc_fac));
  203. }
  204. /* compute gain[n] = agc_fac * gain[n-1]
  205. + (1-agc_fac) * sqrt(gain_in/gain_out) */
  206. /* sig_out[n] = gain[n] * sig_out[n] */
  207. gain = st->past_gain; move16 ();
  208. for (i = 0; i < l_trm; i++)
  209. {
  210. gain = mult_ex (gain, agc_fac);
  211. gain = add_ex (gain, g0);
  212. sig_out[i] = extract_h_ex (L_shl_ex (L_mult_ex (sig_out[i], gain), 3));
  213. move16 ();
  214. }
  215. st->past_gain = gain; move16 ();
  216. return 0;
  217. }
  218. /*
  219. **************************************************************************
  220. *
  221. * Function : agc2
  222. * Purpose : Scales the excitation on a subframe basis
  223. *
  224. **************************************************************************
  225. */
  226. void agc2 (
  227. Word16 *sig_in, /* i : postfilter input signal */
  228. Word16 *sig_out, /* i/o : postfilter output signal */
  229. Word16 l_trm /* i : subframe size */
  230. )
  231. {
  232. Word16 i, exp;
  233. Word16 gain_in, gain_out, g0;
  234. Word32 s;
  235. /* calculate gain_out with exponent */
  236. s = energy_new(sig_out, l_trm); move32 (); /* function result */
  237. test ();
  238. if (s == 0)
  239. {
  240. return;
  241. }
  242. exp = sub_ex (norm_l_ex (s), 1);
  243. gain_out = round_ex (L_shl_ex (s, exp));
  244. /* calculate gain_in with exponent */
  245. s = energy_new(sig_in, l_trm); move32 (); /* function result */
  246. test ();
  247. if (s == 0)
  248. {
  249. g0 = 0; move16 ();
  250. }
  251. else
  252. {
  253. i = norm_l_ex (s);
  254. gain_in = round_ex (L_shl_ex (s, i));
  255. exp = sub_ex (exp, i);
  256. /*---------------------------------------------------*
  257. * g0 = sqrt(gain_in/gain_out); *
  258. *---------------------------------------------------*/
  259. s = L_deposit_l_ex (div_s (gain_out, gain_in));
  260. s = L_shl_ex (s, 7); /* s = gain_out / gain_in */
  261. s = L_shr_ex (s, exp); /* add exponent */
  262. s = Inv_sqrt_ex (s); move32 (); /* function result */
  263. g0 = round_ex (L_shl_ex (s, 9));
  264. }
  265. /* sig_out(n) = gain(n) sig_out(n) */
  266. for (i = 0; i < l_trm; i++)
  267. {
  268. sig_out[i] = extract_h_ex (L_shl_ex (L_mult_ex (sig_out[i], g0), 3));
  269. move16 ();
  270. }
  271. return;
  272. }