p_ol_wgh.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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 : p_ol_wgh.c
  11. * Purpose : Compute the open loop pitch lag with weighting
  12. *
  13. *************************************************************************/
  14. /*
  15. ********************************************************************************
  16. * MODULE INCLUDE FILE AND VERSION ID
  17. ********************************************************************************
  18. */
  19. #include "p_ol_wgh.h"
  20. const char p_ol_wgh_id[] = "@(#)$Id $" p_ol_wgh_h;
  21. /*
  22. *****************************************************************************
  23. * INCLUDE FILES
  24. *****************************************************************************
  25. */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include "typedef.h"
  29. #include "basic_op.h"
  30. #include "oper_32b.h"
  31. #include "count.h"
  32. #include "cnst.h"
  33. #include "corrwght.tab"
  34. #include "gmed_n.h"
  35. #include "inv_sqrt_ex.h"
  36. #include "vad.h"
  37. #include "calc_cor.h"
  38. #include "hp_max.h"
  39. /*
  40. *****************************************************************************
  41. * LOCAL VARIABLES AND TABLES
  42. *****************************************************************************
  43. */
  44. /*************************************************************************
  45. *
  46. * FUNCTION: Lag_max
  47. *
  48. * PURPOSE: Find the lag that has maximum correlation of scal_sig[] in a
  49. * given delay range.
  50. *
  51. * DESCRIPTION:
  52. * The correlation is given by
  53. * cor[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max
  54. * The functions outputs the maximum correlation after normalization
  55. * and the corresponding lag.
  56. *
  57. *************************************************************************/
  58. static Word16 Lag_max ( /* o : lag found */
  59. vadState *vadSt, /* i/o : VAD state struct */
  60. Word32 corr[], /* i : correlation vector. */
  61. Word16 scal_sig[], /* i : scaled signal. */
  62. Word16 L_frame, /* i : length of frame to compute pitch */
  63. Word16 lag_max, /* i : maximum lag */
  64. Word16 lag_min, /* i : minimum lag */
  65. Word16 old_lag, /* i : old open-loop lag */
  66. Word16 *cor_max, /* o : normalized correlation of selected lag */
  67. Word16 wght_flg, /* i : is weighting function used */
  68. Word16 *gain_flg, /* o : open-loop flag */
  69. Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */
  70. )
  71. {
  72. Word16 i, j;
  73. Word16 *p, *p1;
  74. Word32 max, t0;
  75. Word16 t0_h, t0_l;
  76. Word16 p_max;
  77. const Word16 *ww, *we;
  78. Word32 t1;
  79. ww = &corrweight[250]; move16 ();
  80. we = &corrweight[123 + lag_max - old_lag]; move16 ();
  81. max = MIN_32; move32 ();
  82. p_max = lag_max; move16 ();
  83. for (i = lag_max; i >= lag_min; i--)
  84. {
  85. t0 = corr[-i]; move32 ();
  86. /* Weighting of the correlation function. */
  87. L_Extract (corr[-i], &t0_h, &t0_l);
  88. t0 = Mpy_32_16 (t0_h, t0_l, *ww);
  89. ww--; move16();
  90. test ();
  91. if (wght_flg > 0) {
  92. /* Weight the neighbourhood of the old lag. */
  93. L_Extract (t0, &t0_h, &t0_l);
  94. t0 = Mpy_32_16 (t0_h, t0_l, *we);
  95. we--; move16();
  96. }
  97. test ();
  98. if (L_sub_ex (t0, max) >= 0)
  99. {
  100. max = t0; move32 ();
  101. p_max = i; move16 ();
  102. }
  103. }
  104. p = &scal_sig[0]; move16 ();
  105. p1 = &scal_sig[-p_max]; move16 ();
  106. t0 = 0; move32 ();
  107. t1 = 0; move32 ();
  108. for (j = 0; j < L_frame; j++, p++, p1++)
  109. {
  110. t0 = L_mac_ex (t0, *p, *p1);
  111. t1 = L_mac_ex (t1, *p1, *p1);
  112. }
  113. if (dtx)
  114. { /* no test() call since this if is only in simulation env */
  115. #ifdef VAD2
  116. vadSt->L_Rmax = L_add_ex(vadSt->L_Rmax, t0); /* Save max correlation */
  117. vadSt->L_R0 = L_add_ex(vadSt->L_R0, t1); /* Save max energy */
  118. #else
  119. /* update and detect tone */
  120. vad_tone_detection_update (vadSt, 0);
  121. vad_tone_detection (vadSt, t0, t1);
  122. #endif
  123. }
  124. /* gain flag is set according to the open_loop gain */
  125. /* is t2/t1 > 0.4 ? */
  126. *gain_flg = round_ex(L_msu_ex(t0, round_ex(t1), 13107)); move16();
  127. *cor_max = 0; move16 ();
  128. return (p_max);
  129. }
  130. /*
  131. *****************************************************************************
  132. * PUBLIC PROGRAM CODE
  133. *****************************************************************************
  134. */
  135. /*************************************************************************
  136. *
  137. * Function: p_ol_wgh_init
  138. * Purpose: Allocates state memory and initializes state memory
  139. *
  140. **************************************************************************
  141. */
  142. int p_ol_wgh_init (pitchOLWghtState **state)
  143. {
  144. pitchOLWghtState* s;
  145. if (state == (pitchOLWghtState **) NULL){
  146. wfprintf(stderr, "p_ol_wgh_init: invalid parameter\n");
  147. return -1;
  148. }
  149. *state = NULL;
  150. /* allocate memory */
  151. if ((s= (pitchOLWghtState *) wmalloc(sizeof(pitchOLWghtState))) == NULL){
  152. wfprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n");
  153. return -1;
  154. }
  155. p_ol_wgh_reset(s);
  156. *state = s;
  157. return 0;
  158. }
  159. /*************************************************************************
  160. *
  161. * Function: p_ol_wgh_reset
  162. * Purpose: Initializes state memory to zero
  163. *
  164. **************************************************************************
  165. */
  166. int p_ol_wgh_reset (pitchOLWghtState *st)
  167. {
  168. if (st == (pitchOLWghtState *) NULL){
  169. wfprintf(stderr, "p_ol_wgh_reset: invalid parameter\n");
  170. return -1;
  171. }
  172. /* Reset pitch search states */
  173. st->old_T0_med = 40;
  174. st->ada_w = 0;
  175. st->wght_flg = 0;
  176. return 0;
  177. }
  178. /*************************************************************************
  179. *
  180. * Function: p_ol_wgh_exit
  181. * Purpose: The memory used for state memory is freed
  182. *
  183. **************************************************************************
  184. */
  185. void p_ol_wgh_exit (pitchOLWghtState **state)
  186. {
  187. if (state == NULL || *state == NULL)
  188. return;
  189. /* deallocate memory */
  190. wfree(*state);
  191. *state = NULL;
  192. return;
  193. }
  194. /*************************************************************************
  195. *
  196. * Function: p_ol_wgh
  197. * Purpose: open-loop pitch search with weighting
  198. *
  199. **************************************************************************
  200. */
  201. Word16 Pitch_ol_wgh ( /* o : open loop pitch lag */
  202. pitchOLWghtState *st, /* i/o : State struct */
  203. vadState *vadSt, /* i/o : VAD state struct */
  204. Word16 signal[], /* i : signal used to compute the open loop pitch */
  205. /* signal[-pit_max] to signal[-1] should be known */
  206. Word16 pit_min, /* i : minimum pitch lag */
  207. Word16 pit_max, /* i : maximum pitch lag */
  208. Word16 L_frame, /* i : length of frame to compute pitch */
  209. Word16 old_lags[], /* i : history with old stored Cl lags */
  210. Word16 ol_gain_flg[], /* i : OL gain flag */
  211. Word16 idx, /* i : index */
  212. Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */
  213. )
  214. {
  215. Word16 i;
  216. Word16 max1;
  217. Word16 p_max1;
  218. Word32 t0;
  219. #ifndef VAD2
  220. Word16 corr_hp_max;
  221. #endif
  222. Word32 corr[PIT_MAX+1], *corr_ptr;
  223. /* Scaled signal */
  224. Word16 scaled_signal[PIT_MAX + L_FRAME];
  225. Word16 *scal_sig;
  226. scal_sig = &scaled_signal[pit_max]; move16 ();
  227. t0 = 0L; move32 ();
  228. for (i = -pit_max; i < L_frame; i++)
  229. {
  230. t0 = L_mac_ex (t0, signal[i], signal[i]);
  231. }
  232. /*--------------------------------------------------------*
  233. * Scaling of input signal. *
  234. * *
  235. * if Overflow -> scal_sig[i] = signal[i]>>2 *
  236. * else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2 *
  237. * else -> scal_sig[i] = signal[i] *
  238. *--------------------------------------------------------*/
  239. /*--------------------------------------------------------*
  240. * Verification for risk of overflow. *
  241. *--------------------------------------------------------*/
  242. test (); test ();
  243. if (L_sub_ex (t0, MAX_32) == 0L) /* Test for overflow */
  244. {
  245. for (i = -pit_max; i < L_frame; i++)
  246. {
  247. scal_sig[i] = shr_ex (signal[i], 3); move16 ();
  248. }
  249. }
  250. else if (L_sub_ex (t0, (Word32) 1048576L) < (Word32) 0)
  251. {
  252. for (i = -pit_max; i < L_frame; i++)
  253. {
  254. scal_sig[i] = shl_ex (signal[i], 3); move16 ();
  255. }
  256. }
  257. else
  258. {
  259. for (i = -pit_max; i < L_frame; i++)
  260. {
  261. scal_sig[i] = signal[i]; move16 ();
  262. }
  263. }
  264. /* calculate all coreelations of scal_sig, from pit_min to pit_max */
  265. corr_ptr = &corr[pit_max]; move32 ();
  266. comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr);
  267. p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
  268. st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
  269. dtx);
  270. move16 ();
  271. test (); move16 ();
  272. if (ol_gain_flg[idx] > 0)
  273. {
  274. /* Calculate 5-point median of previous lags */
  275. for (i = 4; i > 0; i--) /* Shift buffer */
  276. {
  277. old_lags[i] = old_lags[i-1]; move16 ();
  278. }
  279. old_lags[0] = p_max1; move16 ();
  280. st->old_T0_med = gmed_n (old_lags, 5); move16 ();
  281. st->ada_w = 32767; move16 (); /* Q15 = 1.0 */
  282. }
  283. else
  284. {
  285. st->old_T0_med = p_max1; move16 ();
  286. st->ada_w = mult_ex(st->ada_w, 29491); /* = ada_w = ada_w * 0.9 */
  287. }
  288. test ();
  289. if (sub_ex(st->ada_w, 9830) < 0) /* ada_w - 0.3 */
  290. {
  291. st->wght_flg = 0; move16 ();
  292. }
  293. else
  294. {
  295. st->wght_flg = 1; move16 ();
  296. }
  297. #ifndef VAD2
  298. if (dtx)
  299. { /* no test() call since this if is only in simulation env */
  300. test ();
  301. if (sub_ex(idx, 1) == 0)
  302. {
  303. /* calculate max high-passed filtered correlation of all lags */
  304. hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max);
  305. /* update complex background detector */
  306. vad_complex_detection_update(vadSt, corr_hp_max);
  307. }
  308. }
  309. #endif
  310. return (p_max1);
  311. }