ph_disp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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 : ph_disp.c
  11. * Purpose : Perform adaptive phase dispersion of the excitation
  12. * signal.
  13. *
  14. ********************************************************************************
  15. */
  16. /*
  17. ********************************************************************************
  18. * MODULE INCLUDE FILE AND VERSION ID
  19. ********************************************************************************
  20. */
  21. #include "ph_disp.h"
  22. const char ph_disp_id[] = "@(#)$Id $" ph_disp_h;
  23. /*
  24. ********************************************************************************
  25. * INCLUDE FILES
  26. ********************************************************************************
  27. */
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include "typedef.h"
  31. #include "basic_op.h"
  32. #include "count.h"
  33. #include "cnst.h"
  34. #include "copy.h"
  35. /*
  36. ********************************************************************************
  37. * LOCAL VARIABLES AND TABLES
  38. ********************************************************************************
  39. */
  40. #include "ph_disp.tab"
  41. /*
  42. ********************************************************************************
  43. * PUBLIC PROGRAM CODE
  44. ********************************************************************************
  45. */
  46. /*************************************************************************
  47. *
  48. * Function: ph_disp_init
  49. *
  50. **************************************************************************
  51. */
  52. int ph_disp_init (ph_dispState **state)
  53. {
  54. ph_dispState *s;
  55. if (state == (ph_dispState **) NULL){
  56. wfprintf(stderr, "ph_disp_init: invalid parameter\n");
  57. return -1;
  58. }
  59. *state = NULL;
  60. /* allocate memory */
  61. if ((s= (ph_dispState *) wmalloc(sizeof(ph_dispState))) == NULL){
  62. wfprintf(stderr, "ph_disp_init: can not malloc state structure\n");
  63. return -1;
  64. }
  65. ph_disp_reset(s);
  66. *state = s;
  67. return 0;
  68. }
  69. /*************************************************************************
  70. *
  71. * Function: ph_disp_reset
  72. *
  73. **************************************************************************
  74. */
  75. int ph_disp_reset (ph_dispState *state)
  76. {
  77. Word16 i;
  78. if (state == (ph_dispState *) NULL){
  79. wfprintf(stderr, "ph_disp_reset: invalid parameter\n");
  80. return -1;
  81. }
  82. for (i=0; i<PHDGAINMEMSIZE; i++)
  83. {
  84. state->gainMem[i] = 0;
  85. }
  86. state->prevState = 0;
  87. state->prevCbGain = 0;
  88. state->lockFull = 0;
  89. state->onset = 0; /* assume no onset in start */
  90. return 0;
  91. }
  92. /*************************************************************************
  93. *
  94. * Function: ph_disp_exit
  95. *
  96. **************************************************************************
  97. */
  98. void ph_disp_exit (ph_dispState **state)
  99. {
  100. if ((state == NULL) || (*state == NULL))
  101. return;
  102. /* deallocate memory */
  103. wfree(*state);
  104. *state = NULL;
  105. return;
  106. }
  107. /*************************************************************************
  108. *
  109. * Function: ph_disp_lock
  110. *
  111. **************************************************************************
  112. */
  113. void ph_disp_lock (ph_dispState *state)
  114. {
  115. state->lockFull = 1;
  116. return;
  117. }
  118. /*************************************************************************
  119. *
  120. * Function: ph_disp_release
  121. *
  122. **************************************************************************
  123. */
  124. void ph_disp_release (ph_dispState *state)
  125. {
  126. state->lockFull = 0;
  127. return;
  128. }
  129. /*************************************************************************
  130. *
  131. * Function: ph_disp
  132. *
  133. * Adaptive phase dispersion; forming of total excitation
  134. * (for synthesis part of decoder)
  135. *
  136. **************************************************************************
  137. */
  138. void ph_disp (
  139. ph_dispState *state, /* i/o : State struct */
  140. enum Mode mode, /* i : codec mode */
  141. Word16 x[], /* i/o Q0 : in: LTP excitation signal */
  142. /* out: total excitation signal */
  143. Word16 cbGain, /* i Q1 : Codebook gain */
  144. Word16 ltpGain, /* i Q14 : LTP gain */
  145. Word16 inno[], /* i/o Q13 : Innovation vector (Q12 for 12.2) */
  146. Word16 pitch_fac, /* i Q14 : pitch factor used to scale the
  147. LTP excitation (Q13 for 12.2) */
  148. Word16 tmp_shift /* i Q0 : shift factor applied to sum of
  149. scaled LTP ex & innov. before
  150. rounding */
  151. )
  152. {
  153. Word16 i, i1;
  154. Word16 tmp1;
  155. Word32 L_temp;
  156. Word16 impNr; /* indicator for amount of disp./filter used */
  157. Word16 inno_sav[L_SUBFR];
  158. Word16 ps_poss[L_SUBFR];
  159. Word16 j, nze, nPulse, ppos;
  160. const Word16 *ph_imp; /* Pointer to phase dispersion filter */
  161. /* Update LTP gain memory */
  162. for (i = PHDGAINMEMSIZE-1; i > 0; i--)
  163. {
  164. state->gainMem[i] = state->gainMem[i-1]; move16 ();
  165. }
  166. state->gainMem[0] = ltpGain; move16 ();
  167. /* basic adaption of phase dispersion */
  168. test ();
  169. if (sub_ex(ltpGain, PHDTHR2LTP) < 0) { /* if (ltpGain < 0.9) */
  170. test ();
  171. if (sub_ex(ltpGain, PHDTHR1LTP) > 0)
  172. { /* if (ltpGain > 0.6 */
  173. impNr = 1; /* medium dispersion */ move16 ();
  174. }
  175. else
  176. {
  177. impNr = 0; /* maximum dispersion */ move16 ();
  178. }
  179. }
  180. else
  181. {
  182. impNr = 2; /* no dispersion */ move16 ();
  183. }
  184. /* onset indicator */
  185. /* onset = (cbGain > onFact * cbGainMem[0]) */
  186. move32 ();
  187. tmp1 = round_ex(L_shl_ex(L_mult_ex(state->prevCbGain, ONFACTPLUS1), 2));
  188. test ();
  189. if (sub_ex(cbGain, tmp1) > 0)
  190. {
  191. state->onset = ONLENGTH; move16 ();
  192. }
  193. else
  194. {
  195. test ();
  196. if (state->onset > 0)
  197. {
  198. state->onset = sub_ex (state->onset, 1); move16 ();
  199. }
  200. }
  201. /* if not onset, check ltpGain buffer and use max phase dispersion if
  202. half or more of the ltpGain-parameters say so */
  203. test ();
  204. if (state->onset == 0)
  205. {
  206. /* Check LTP gain memory and set filter accordingly */
  207. i1 = 0; move16 ();
  208. for (i = 0; i < PHDGAINMEMSIZE; i++)
  209. {
  210. test ();
  211. if (sub_ex(state->gainMem[i], PHDTHR1LTP) < 0)
  212. {
  213. i1 = add_ex (i1, 1);
  214. }
  215. }
  216. test ();
  217. if (sub_ex(i1, 2) > 0)
  218. {
  219. impNr = 0; move16 ();
  220. }
  221. }
  222. /* Restrict decrease in phase dispersion to one step if not onset */
  223. test (); test ();
  224. if ((sub_ex(impNr, add_ex(state->prevState, 1)) > 0) && (state->onset == 0))
  225. {
  226. impNr = sub_ex (impNr, 1);
  227. }
  228. /* if onset, use one step less phase dispersion */
  229. test (); test ();
  230. if((sub_ex(impNr, 2) < 0) && (state->onset > 0))
  231. {
  232. impNr = add_ex (impNr, 1);
  233. }
  234. /* disable for very low levels */
  235. test ();
  236. if(sub_ex(cbGain, 10) < 0)
  237. {
  238. impNr = 2; move16 ();
  239. }
  240. test ();
  241. if(sub_ex(state->lockFull, 1) == 0)
  242. {
  243. impNr = 0; move16 ();
  244. }
  245. /* update static memory */
  246. state->prevState = impNr; move16 ();
  247. state->prevCbGain = cbGain; move16 ();
  248. /* do phase dispersion for all modes but 12.2 and 7.4;
  249. don't modify the innovation if impNr >=2 (= no phase disp) */
  250. test (); test (); test(); test();
  251. if (sub_ex(mode, MR122) != 0 &&
  252. sub_ex(mode, MR102) != 0 &&
  253. sub_ex(mode, MR74) != 0 &&
  254. sub_ex(impNr, 2) < 0)
  255. {
  256. /* track pulse positions, save innovation,
  257. and initialize new innovation */
  258. nze = 0; move16 ();
  259. for (i = 0; i < L_SUBFR; i++)
  260. {
  261. move16 (); test();
  262. if (inno[i] != 0)
  263. {
  264. ps_poss[nze] = i; move16 ();
  265. nze = add_ex (nze, 1);
  266. }
  267. inno_sav[i] = inno[i]; move16 ();
  268. inno[i] = 0; move16 ();
  269. }
  270. /* Choose filter corresponding to codec mode and dispersion criterium */
  271. test ();
  272. if (sub_ex (mode, MR795) == 0)
  273. {
  274. test ();
  275. if (impNr == 0)
  276. {
  277. ph_imp = ph_imp_low_MR795; move16 ();
  278. }
  279. else
  280. {
  281. ph_imp = ph_imp_mid_MR795; move16 ();
  282. }
  283. }
  284. else
  285. {
  286. test ();
  287. if (impNr == 0)
  288. {
  289. ph_imp = ph_imp_low; move16 ();
  290. }
  291. else
  292. {
  293. ph_imp = ph_imp_mid; move16 ();
  294. }
  295. }
  296. /* Do phase dispersion of innovation */
  297. for (nPulse = 0; nPulse < nze; nPulse++)
  298. {
  299. ppos = ps_poss[nPulse]; move16 ();
  300. /* circular convolution with impulse response */
  301. j = 0; move16 ();
  302. for (i = ppos; i < L_SUBFR; i++)
  303. {
  304. /* inno[i1] += inno_sav[ppos] * ph_imp[i1-ppos] */
  305. tmp1 = mult_ex(inno_sav[ppos], ph_imp[j++]);
  306. inno[i] = add_ex(inno[i], tmp1); move16 ();
  307. }
  308. for (i = 0; i < ppos; i++)
  309. {
  310. /* inno[i] += inno_sav[ppos] * ph_imp[L_SUBFR-ppos+i] */
  311. tmp1 = mult_ex(inno_sav[ppos], ph_imp[j++]);
  312. inno[i] = add_ex(inno[i], tmp1); move16 ();
  313. }
  314. }
  315. }
  316. /* compute total excitation for synthesis part of decoder
  317. (using modified innovation if phase dispersion is active) */
  318. for (i = 0; i < L_SUBFR; i++)
  319. {
  320. /* x[i] = gain_pit*x[i] + cbGain*code[i]; */
  321. L_temp = L_mult_ex ( x[i], pitch_fac);
  322. /* 12.2: Q0 * Q13 */
  323. /* 7.4: Q0 * Q14 */
  324. L_temp = L_mac_ex (L_temp, inno[i], cbGain);
  325. /* 12.2: Q12 * Q1 */
  326. /* 7.4: Q13 * Q1 */
  327. L_temp = L_shl_ex (L_temp, tmp_shift); /* Q16 */
  328. x[i] = round_ex (L_temp); move16 ();
  329. }
  330. return;
  331. }