pstfilt.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*************************************************************************
  2. *
  3. * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
  4. * R99 Version 3.3.0
  5. * REL-4 Version 4.1.0
  6. *
  7. ********************************************************************************
  8. *
  9. * File : pstfilt.c
  10. * Purpose : Performs adaptive postfiltering on the synthesis
  11. * : speech
  12. *
  13. ********************************************************************************
  14. */
  15. /*
  16. ********************************************************************************
  17. * MODULE INCLUDE FILE AND VERSION ID
  18. ********************************************************************************
  19. */
  20. #include "pstfilt.h"
  21. const char pstfilt_id[] = "@(#)$Id $" pstfilt_h;
  22. /*
  23. ********************************************************************************
  24. * INCLUDE FILES
  25. ********************************************************************************
  26. */
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include "typedef.h"
  30. #include "mode.h"
  31. #include "basic_op.h"
  32. #include "set_zero.h"
  33. #include "weight_a.h"
  34. #include "residu.h"
  35. #include "copy.h"
  36. #include "syn_filt.h"
  37. #include "preemph.h"
  38. #include "count.h"
  39. #include "cnst.h"
  40. /*
  41. ********************************************************************************
  42. * LOCAL VARIABLES AND TABLES
  43. ********************************************************************************
  44. */
  45. /*---------------------------------------------------------------*
  46. * Postfilter constant parameters (defined in "cnst.h") *
  47. *---------------------------------------------------------------*
  48. * L_FRAME : Frame size. *
  49. * L_SUBFR : Sub-frame size. *
  50. * M : LPC order. *
  51. * MP1 : LPC order+1 *
  52. * MU : Factor for tilt compensation filter *
  53. * AGC_FAC : Factor for automatic gain control *
  54. *---------------------------------------------------------------*/
  55. #define L_H 22 /* size of truncated impulse response of A(z/g1)/A(z/g2) */
  56. /* Spectral expansion factors */
  57. static const Word16 gamma3_MR122[M] = {
  58. 22938, 16057, 11240, 7868, 5508,
  59. 3856, 2699, 1889, 1322, 925
  60. };
  61. static const Word16 gamma3[M] = {
  62. 18022, 9912, 5451, 2998, 1649, 907, 499, 274, 151, 83
  63. };
  64. static const Word16 gamma4_MR122[M] = {
  65. 24576, 18432, 13824, 10368, 7776,
  66. 5832, 4374, 3281, 2461, 1846
  67. };
  68. static const Word16 gamma4[M] = {
  69. 22938, 16057, 11240, 7868, 5508, 3856, 2699, 1889, 1322, 925
  70. };
  71. /*
  72. ********************************************************************************
  73. * PUBLIC PROGRAM CODE
  74. ********************************************************************************
  75. */
  76. /*************************************************************************
  77. *
  78. * Function: Post_Filter_init
  79. * Purpose: Allocates memory for filter structure and initializes
  80. * state memory
  81. *
  82. **************************************************************************
  83. */
  84. int Post_Filter_init (Post_FilterState **state)
  85. {
  86. Post_FilterState* s;
  87. if (state == (Post_FilterState **) NULL){
  88. wfprintf(stderr, "Post_Filter_init: invalid parameter\n");
  89. return -1;
  90. }
  91. *state = NULL;
  92. /* allocate memory */
  93. if ((s= (Post_FilterState *) wmalloc(sizeof(Post_FilterState))) == NULL){
  94. wfprintf(stderr, "Post_Filter_init: can not malloc state structure\n");
  95. return -1;
  96. }
  97. s->preemph_state = NULL;
  98. s->agc_state = NULL;
  99. if (preemphasis_init(&s->preemph_state) || agc_init(&s->agc_state)) {
  100. Post_Filter_exit(&s);
  101. return -1;
  102. }
  103. Post_Filter_reset(s);
  104. *state = s;
  105. return 0;
  106. }
  107. /*************************************************************************
  108. *
  109. * Function: Post_Filter_reset
  110. * Purpose: Initializes state memory to zero
  111. *
  112. **************************************************************************
  113. */
  114. int Post_Filter_reset (Post_FilterState *state)
  115. {
  116. if (state == (Post_FilterState *) NULL){
  117. wfprintf(stderr, "Post_Filter_reset: invalid parameter\n");
  118. return -1;
  119. }
  120. Set_zero (state->mem_syn_pst, M);
  121. Set_zero (state->res2, L_SUBFR);
  122. Set_zero (state->synth_buf, L_FRAME + M);
  123. agc_reset(state->agc_state);
  124. preemphasis_reset(state->preemph_state);
  125. return 0;
  126. }
  127. /*************************************************************************
  128. *
  129. * Function: Post_Filter_exit
  130. * Purpose: The memory used for state memory is freed
  131. *
  132. **************************************************************************
  133. */
  134. void Post_Filter_exit (Post_FilterState **state)
  135. {
  136. if (state == NULL || *state == NULL)
  137. return;
  138. agc_exit(&(*state)->agc_state);
  139. preemphasis_exit(&(*state)->preemph_state);
  140. /* deallocate memory */
  141. wfree(*state);
  142. *state = NULL;
  143. return;
  144. }
  145. /*
  146. **************************************************************************
  147. * Function: Post_Filter
  148. * Purpose: postfiltering of synthesis speech.
  149. * Description:
  150. * The postfiltering process is described as follows:
  151. *
  152. * - inverse filtering of syn[] through A(z/0.7) to get res2[]
  153. * - tilt compensation filtering; 1 - MU*k*z^-1
  154. * - synthesis filtering through 1/A(z/0.75)
  155. * - adaptive gain control
  156. *
  157. **************************************************************************
  158. */
  159. int Post_Filter (
  160. Post_FilterState *st, /* i/o : post filter states */
  161. enum Mode mode, /* i : AMR mode */
  162. Word16 *syn, /* i/o : synthesis speech (postfiltered is output) */
  163. Word16 *Az_4 /* i : interpolated LPC parameters in all subfr. */
  164. )
  165. {
  166. /*-------------------------------------------------------------------*
  167. * Declaration of parameters *
  168. *-------------------------------------------------------------------*/
  169. Word16 Ap3[MP1], Ap4[MP1]; /* bandwidth expanded LP parameters */
  170. Word16 *Az; /* pointer to Az_4: */
  171. /* LPC parameters in each subframe */
  172. Word16 i_subfr; /* index for beginning of subframe */
  173. Word16 h[L_H];
  174. Word16 i;
  175. Word16 temp1, temp2;
  176. Word32 L_tmp;
  177. Word16 *syn_work = &st->synth_buf[M]; move16 ();
  178. /*-----------------------------------------------------*
  179. * Post filtering *
  180. *-----------------------------------------------------*/
  181. Copy (syn, syn_work , L_FRAME);
  182. Az = Az_4;
  183. for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
  184. {
  185. /* Find weighted filter coefficients Ap3[] and ap[4] */
  186. test (); test ();
  187. if (sub_ex(mode, MR122) == 0 || sub_ex(mode, MR102) == 0)
  188. {
  189. Weight_Ai (Az, gamma3_MR122, Ap3);
  190. Weight_Ai (Az, gamma4_MR122, Ap4);
  191. }
  192. else
  193. {
  194. Weight_Ai (Az, gamma3, Ap3);
  195. Weight_Ai (Az, gamma4, Ap4);
  196. }
  197. /* filtering of synthesis speech by A(z/0.7) to find res2[] */
  198. Residu (Ap3, &syn_work[i_subfr], st->res2, L_SUBFR);
  199. /* tilt compensation filter */
  200. /* impulse response of A(z/0.7)/A(z/0.75) */
  201. Copy (Ap3, h, M + 1);
  202. Set_zero (&h[M + 1], L_H - M - 1);
  203. Syn_filt (Ap4, h, h, L_H, &h[M + 1], 0);
  204. /* 1st correlation of h[] */
  205. L_tmp = L_mult_ex (h[0], h[0]);
  206. for (i = 1; i < L_H; i++)
  207. {
  208. L_tmp = L_mac_ex (L_tmp, h[i], h[i]);
  209. }
  210. temp1 = extract_h_ex (L_tmp);
  211. L_tmp = L_mult_ex (h[0], h[1]);
  212. for (i = 1; i < L_H - 1; i++)
  213. {
  214. L_tmp = L_mac_ex (L_tmp, h[i], h[i + 1]);
  215. }
  216. temp2 = extract_h_ex (L_tmp);
  217. test ();
  218. if (temp2 <= 0)
  219. {
  220. temp2 = 0; move16 ();
  221. }
  222. else
  223. {
  224. temp2 = mult_ex (temp2, MU);
  225. temp2 = div_s (temp2, temp1);
  226. }
  227. preemphasis (st->preemph_state, st->res2, temp2, L_SUBFR);
  228. /* filtering through 1/A(z/0.75) */
  229. Syn_filt (Ap4, st->res2, &syn[i_subfr], L_SUBFR, st->mem_syn_pst, 1);
  230. /* scale output to input */
  231. agc (st->agc_state, &syn_work[i_subfr], &syn[i_subfr],
  232. AGC_FAC, L_SUBFR);
  233. Az += MP1;
  234. }
  235. /* update syn_work[] buffer */
  236. Copy (&syn_work[L_FRAME - M], &syn_work[-M], M);
  237. return 0;
  238. }