pitch_fr.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  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 : pitch_fr.c
  11. * Purpose : Find the pitch period with 1/3 or 1/6 subsample
  12. * : resolution (closed loop).
  13. *
  14. ********************************************************************************
  15. */
  16. /*
  17. ********************************************************************************
  18. * MODULE INCLUDE FILE AND VERSION ID
  19. ********************************************************************************
  20. */
  21. #include "pitch_fr.h"
  22. const char pitch_fr_id[] = "@(#)$Id $" pitch_fr_h;
  23. /*
  24. ********************************************************************************
  25. * INCLUDE FILES
  26. ********************************************************************************
  27. */
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include "typedef.h"
  31. #include "basic_op.h"
  32. #include "oper_32b.h"
  33. #include "count.h"
  34. #include "cnst.h"
  35. #include "enc_lag3.h"
  36. #include "enc_lag6.h"
  37. #include "inter_36.h"
  38. #include "inv_sqrt_ex.h"
  39. #include "convolve.h"
  40. /*
  41. ********************************************************************************
  42. * LOCAL VARIABLES AND TABLES
  43. ********************************************************************************
  44. */
  45. /*
  46. * mode dependent parameters used in Pitch_fr()
  47. * Note: order of MRxx in 'enum Mode' is important!
  48. */
  49. static const struct {
  50. Word16 max_frac_lag; /* lag up to which fractional lags are used */
  51. Word16 flag3; /* enable 1/3 instead of 1/6 fract. resolution */
  52. Word16 first_frac; /* first fractional to check */
  53. Word16 last_frac; /* last fractional to check */
  54. Word16 delta_int_low; /* integer lag below TO to start search from */
  55. Word16 delta_int_range; /* integer range around T0 */
  56. Word16 delta_frc_low; /* fractional below T0 */
  57. Word16 delta_frc_range; /* fractional range around T0 */
  58. Word16 pit_min; /* minimum pitch */
  59. } mode_dep_parm[N_MODES] = {
  60. /* MR475 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN },
  61. /* MR515 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN },
  62. /* MR59 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
  63. /* MR67 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
  64. /* MR74 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
  65. /* MR795 */ { 84, 1, -2, 2, 3, 6, 10, 19, PIT_MIN },
  66. /* MR102 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
  67. /* MR122 */ { 94, 0, -3, 3, 3, 6, 5, 9, PIT_MIN_MR122 }
  68. };
  69. /*
  70. ********************************************************************************
  71. * LOCAL PROGRAM CODE
  72. ********************************************************************************
  73. */
  74. /*************************************************************************
  75. *
  76. * FUNCTION: Norm_Corr()
  77. *
  78. * PURPOSE: Find the normalized correlation between the target vector
  79. * and the filtered past excitation.
  80. *
  81. * DESCRIPTION:
  82. * The normalized correlation is given by the correlation between the
  83. * target and filtered past excitation divided by the square root of
  84. * the energy of filtered excitation.
  85. * corr[k] = <x[], y_k[]>/sqrt(y_k[],y_k[])
  86. * where x[] is the target vector and y_k[] is the filtered past
  87. * excitation at delay k.
  88. *
  89. *************************************************************************/
  90. static void Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr,
  91. Word16 t_min, Word16 t_max, Word16 corr_norm[])
  92. {
  93. Word16 i, j, k;
  94. Word16 corr_h, corr_l, norm_h, norm_l_ex;
  95. Word32 s;
  96. /* Usally dynamic allocation of (L_subfr) */
  97. Word16 excf[L_SUBFR];
  98. Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR];
  99. k = -t_min; move16 ();
  100. /* compute the filtered excitation for the first delay t_min */
  101. Convolve (&exc[k], h, excf, L_subfr);
  102. /* scale "excf[]" to avoid overflow */
  103. for (j = 0; j < L_subfr; j++) {
  104. scaled_excf[j] = shr_ex (excf[j], 2); move16 ();
  105. }
  106. /* Compute 1/sqrt(energy of excf[]) */
  107. s = 0; move32 ();
  108. for (j = 0; j < L_subfr; j++) {
  109. s = L_mac_ex (s, excf[j], excf[j]);
  110. }
  111. test ();
  112. if (L_sub_ex (s, 67108864L) <= 0) { /* if (s <= 2^26) */
  113. s_excf = excf; move16 ();
  114. h_fac = 15 - 12; move16 ();
  115. scaling = 0; move16 ();
  116. }
  117. else {
  118. /* "excf[]" is divided by 2 */
  119. s_excf = scaled_excf; move16 ();
  120. h_fac = 15 - 12 - 2; move16 ();
  121. scaling = 2; move16 ();
  122. }
  123. /* loop for every possible period */
  124. for (i = t_min; i <= t_max; i++) {
  125. /* Compute 1/sqrt(energy of excf[]) */
  126. s = 0; move32 ();
  127. for (j = 0; j < L_subfr; j++) {
  128. s = L_mac_ex (s, s_excf[j], s_excf[j]);
  129. }
  130. s = Inv_sqrt_ex (s);
  131. L_Extract (s, &norm_h, &norm_l_ex);
  132. /* Compute correlation between xn[] and excf[] */
  133. s = 0; move32 ();
  134. for (j = 0; j < L_subfr; j++) {
  135. s = L_mac_ex (s, xn[j], s_excf[j]);
  136. }
  137. L_Extract (s, &corr_h, &corr_l);
  138. /* Normalize correlation = correlation * (1/sqrt(energy)) */
  139. s = Mpy_32 (corr_h, corr_l, norm_h, norm_l_ex);
  140. corr_norm[i] = extract_h_ex (L_shl_ex (s, 16));
  141. move16 ();
  142. /* modify the filtered excitation excf[] for the next iteration */
  143. test ();
  144. if (sub_ex (i, t_max) != 0) {
  145. k--;
  146. for (j = L_subfr - 1; j > 0; j--) {
  147. s = L_mult_ex (exc[k], h[j]);
  148. s = L_shl_ex (s, h_fac);
  149. s_excf[j] = add_ex (extract_h_ex (s), s_excf[j - 1]); move16 ();
  150. }
  151. s_excf[0] = shr_ex (exc[k], scaling); move16 ();
  152. }
  153. }
  154. return;
  155. }
  156. /*************************************************************************
  157. *
  158. * FUNCTION: searchFrac()
  159. *
  160. * PURPOSE: Find fractional pitch
  161. *
  162. * DESCRIPTION:
  163. * The function interpolates the normalized correlation at the
  164. * fractional positions around lag T0. The position at which the
  165. * interpolation function reaches its maximum is the fractional pitch.
  166. * Starting point of the search is frac, end point is last_frac.
  167. * frac is overwritten with the fractional pitch.
  168. *
  169. *************************************************************************/
  170. static void searchFrac (
  171. Word16 *lag, /* i/o : integer pitch */
  172. Word16 *frac, /* i/o : start point of search -
  173. fractional pitch */
  174. Word16 last_frac, /* i : endpoint of search */
  175. Word16 corr[], /* i : normalized correlation */
  176. Word16 flag3 /* i : subsample resolution
  177. (3: =1 / 6: =0) */
  178. )
  179. {
  180. Word16 i;
  181. Word16 max;
  182. Word16 corr_int;
  183. /* Test the fractions around T0 and choose the one which maximizes */
  184. /* the interpolated normalized correlation. */
  185. max = Interpol_3or6 (&corr[*lag], *frac, flag3); move16 (); /* function result */
  186. for (i = add_ex (*frac, 1); i <= last_frac; i++) {
  187. corr_int = Interpol_3or6 (&corr[*lag], i, flag3);
  188. move16 ();
  189. test ();
  190. if (sub_ex (corr_int, max) > 0) {
  191. max = corr_int; move16 ();
  192. *frac = i; move16 ();
  193. }
  194. }
  195. test();
  196. if (flag3 == 0) {
  197. /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */
  198. test ();
  199. if (sub_ex (*frac, -3) == 0) {
  200. *frac = 3; move16 ();
  201. *lag = sub_ex (*lag, 1);
  202. }
  203. }
  204. else {
  205. /* limit the fraction value between -1 and 1 */
  206. test ();
  207. if (sub_ex (*frac, -2) == 0) {
  208. *frac = 1; move16 ();
  209. *lag = sub_ex (*lag, 1);
  210. }
  211. test ();
  212. if (sub_ex (*frac, 2) == 0) {
  213. *frac = -1; move16 ();
  214. *lag = add_ex (*lag, 1);
  215. }
  216. }
  217. }
  218. /*************************************************************************
  219. *
  220. * FUNCTION: getRange()
  221. *
  222. * PURPOSE: Sets range around open-loop pitch or integer pitch of last subframe
  223. *
  224. * DESCRIPTION:
  225. * Takes integer pitch T0 and calculates a range around it with
  226. * t0_min = T0-delta_low and t0_max = (T0-delta_low) + delta_range
  227. * t0_min and t0_max are bounded by pitmin and pitmax
  228. *
  229. *************************************************************************/
  230. static void getRange (
  231. Word16 T0, /* i : integer pitch */
  232. Word16 delta_low, /* i : search start offset */
  233. Word16 delta_range, /* i : search range */
  234. Word16 pitmin, /* i : minimum pitch */
  235. Word16 pitmax, /* i : maximum pitch */
  236. Word16 *t0_min, /* o : search range minimum */
  237. Word16 *t0_max) /* o : search range maximum */
  238. {
  239. *t0_min = sub_ex(T0, delta_low);
  240. test ();
  241. if (sub_ex(*t0_min, pitmin) < 0) {
  242. *t0_min = pitmin; move16();
  243. }
  244. *t0_max = add_ex(*t0_min, delta_range);
  245. test ();
  246. if (sub_ex(*t0_max, pitmax) > 0) {
  247. *t0_max = pitmax; move16();
  248. *t0_min = sub_ex(*t0_max, delta_range);
  249. }
  250. }
  251. /*
  252. ********************************************************************************
  253. * PUBLIC PROGRAM CODE
  254. ********************************************************************************
  255. */
  256. /*************************************************************************
  257. *
  258. * Function: Pitch_fr_init
  259. * Purpose: Allocates state memory and initializes state memory
  260. *
  261. **************************************************************************
  262. */
  263. int Pitch_fr_init (Pitch_frState **state)
  264. {
  265. Pitch_frState* s;
  266. if (state == (Pitch_frState **) NULL){
  267. wfprintf(stderr, "Pitch_fr_init: invalid parameter\n");
  268. return -1;
  269. }
  270. *state = NULL;
  271. /* allocate memory */
  272. if ((s= (Pitch_frState *) wmalloc(sizeof(Pitch_frState))) == NULL){
  273. wfprintf(stderr, "Pitch_fr_init: can not malloc state structure\n");
  274. return -1;
  275. }
  276. Pitch_fr_reset(s);
  277. *state = s;
  278. return 0;
  279. }
  280. /*************************************************************************
  281. *
  282. * Function: Pitch_fr_reset
  283. * Purpose: Initializes state memory to zero
  284. *
  285. **************************************************************************
  286. */
  287. int Pitch_fr_reset (Pitch_frState *state)
  288. {
  289. if (state == (Pitch_frState *) NULL){
  290. wfprintf(stderr, "Pitch_fr_reset: invalid parameter\n");
  291. return -1;
  292. }
  293. state->T0_prev_subframe = 0;
  294. return 0;
  295. }
  296. /*************************************************************************
  297. *
  298. * Function: Pitch_fr_exit
  299. * Purpose: The memory used for state memory is freed
  300. *
  301. **************************************************************************
  302. */
  303. void Pitch_fr_exit (Pitch_frState **state)
  304. {
  305. if (state == NULL || *state == NULL)
  306. return;
  307. /* deallocate memory */
  308. wfree(*state);
  309. *state = NULL;
  310. return;
  311. }
  312. /*************************************************************************
  313. *
  314. * FUNCTION: Pitch_fr()
  315. *
  316. * PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution
  317. * (closed loop).
  318. *
  319. * DESCRIPTION:
  320. * - find the normalized correlation between the target and filtered
  321. * past excitation in the search range.
  322. * - select the delay with maximum normalized correlation.
  323. * - interpolate the normalized correlation at fractions -3/6 to 3/6
  324. * with step 1/6 around the chosen delay.
  325. * - The fraction which gives the maximum interpolated value is chosen.
  326. *
  327. *************************************************************************/
  328. Word16 Pitch_fr ( /* o : pitch period (integer) */
  329. Pitch_frState *st, /* i/o : State struct */
  330. enum Mode mode, /* i : codec mode */
  331. Word16 T_op[], /* i : open loop pitch lags */
  332. Word16 exc[], /* i : excitation buffer Q0 */
  333. Word16 xn[], /* i : target vector Q0 */
  334. Word16 h[], /* i : impulse response of synthesis and
  335. weighting filters Q12 */
  336. Word16 L_subfr, /* i : Length of subframe */
  337. Word16 i_subfr, /* i : subframe offset */
  338. Word16 *pit_frac, /* o : pitch period (fractional) */
  339. Word16 *resu3, /* o : subsample resolution 1/3 (=1) or 1/6 (=0) */
  340. Word16 *ana_index /* o : index of encoding */
  341. )
  342. {
  343. Word16 i;
  344. Word16 t_min, t_max;
  345. Word16 t0_min, t0_max;
  346. Word16 max, lag, frac;
  347. Word16 tmp_lag;
  348. Word16 *corr;
  349. Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */
  350. Word16 max_frac_lag;
  351. Word16 flag3, flag4;
  352. Word16 last_frac;
  353. Word16 delta_int_low, delta_int_range;
  354. Word16 delta_frc_low, delta_frc_range;
  355. Word16 pit_min;
  356. Word16 frame_offset;
  357. Word16 delta_search;
  358. /*-----------------------------------------------------------------------*
  359. * set mode specific variables *
  360. *-----------------------------------------------------------------------*/
  361. max_frac_lag = mode_dep_parm[mode].max_frac_lag; move16 ();
  362. flag3 = mode_dep_parm[mode].flag3; move16 ();
  363. frac = mode_dep_parm[mode].first_frac; move16 ();
  364. last_frac = mode_dep_parm[mode].last_frac; move16 ();
  365. delta_int_low = mode_dep_parm[mode].delta_int_low; move16 ();
  366. delta_int_range = mode_dep_parm[mode].delta_int_range; move16 ();
  367. delta_frc_low = mode_dep_parm[mode].delta_frc_low; move16 ();
  368. delta_frc_range = mode_dep_parm[mode].delta_frc_range; move16 ();
  369. pit_min = mode_dep_parm[mode].pit_min; move16 ();
  370. /*-----------------------------------------------------------------------*
  371. * decide upon full or differential search *
  372. *-----------------------------------------------------------------------*/
  373. delta_search = 1; move16 ();
  374. test (); test ();
  375. if ((i_subfr == 0) || (sub_ex(i_subfr,L_FRAME_BY2) == 0)) {
  376. /* Subframe 1 and 3 */
  377. test (); test (); test ();
  378. if (((sub_ex(mode, MR475) != 0) && (sub_ex(mode, MR515) != 0)) ||
  379. (sub_ex(i_subfr,L_FRAME_BY2) != 0)) {
  380. /* set t0_min, t0_max for full search */
  381. /* this is *not* done for mode MR475, MR515 in subframe 3 */
  382. delta_search = 0; /* no differential search */ move16 ();
  383. /* calculate index into T_op which contains the open-loop */
  384. /* pitch estimations for the 2 big subframes */
  385. frame_offset = 1; move16 ();
  386. test ();
  387. if (i_subfr == 0)
  388. frame_offset = 0; move16 ();
  389. /* get T_op from the corresponding half frame and */
  390. /* set t0_min, t0_max */
  391. getRange (T_op[frame_offset], delta_int_low, delta_int_range,
  392. pit_min, PIT_MAX, &t0_min, &t0_max);
  393. }
  394. else {
  395. /* mode MR475, MR515 and 3. Subframe: delta search as well */
  396. getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
  397. pit_min, PIT_MAX, &t0_min, &t0_max);
  398. }
  399. }
  400. else {
  401. /* for Subframe 2 and 4 */
  402. /* get range around T0 of previous subframe for delta search */
  403. getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
  404. pit_min, PIT_MAX, &t0_min, &t0_max);
  405. }
  406. /*-----------------------------------------------------------------------*
  407. * Find interval to compute normalized correlation *
  408. *-----------------------------------------------------------------------*/
  409. t_min = sub_ex (t0_min, L_INTER_SRCH);
  410. t_max = add_ex (t0_max, L_INTER_SRCH);
  411. corr = &corr_v[-t_min]; move16 ();
  412. /*-----------------------------------------------------------------------*
  413. * Compute normalized correlation between target and filtered excitation *
  414. *-----------------------------------------------------------------------*/
  415. Norm_Corr (exc, xn, h, L_subfr, t_min, t_max, corr);
  416. /*-----------------------------------------------------------------------*
  417. * Find integer pitch *
  418. *-----------------------------------------------------------------------*/
  419. max = corr[t0_min]; move16 ();
  420. lag = t0_min; move16 ();
  421. for (i = t0_min + 1; i <= t0_max; i++) {
  422. test ();
  423. if (sub_ex (corr[i], max) >= 0) {
  424. max = corr[i]; move16 ();
  425. lag = i; move16 ();
  426. }
  427. }
  428. /*-----------------------------------------------------------------------*
  429. * Find fractional pitch *
  430. *-----------------------------------------------------------------------*/
  431. test (); test ();
  432. if ((delta_search == 0) && (sub_ex (lag, max_frac_lag) > 0)) {
  433. /* full search and integer pitch greater than max_frac_lag */
  434. /* fractional search is not needed, set fractional to zero */
  435. frac = 0; move16 ();
  436. }
  437. else {
  438. /* if differential search AND mode MR475 OR MR515 OR MR59 OR MR67 */
  439. /* then search fractional with 4 bits resolution */
  440. test (); test (); test (); test (); test ();
  441. if ((delta_search != 0) &&
  442. ((sub_ex (mode, MR475) == 0) ||
  443. (sub_ex (mode, MR515) == 0) ||
  444. (sub_ex (mode, MR59) == 0) ||
  445. (sub_ex (mode, MR67) == 0))) {
  446. /* modify frac or last_frac according to position of last */
  447. /* integer pitch: either search around integer pitch, */
  448. /* or only on left or right side */
  449. tmp_lag = st->T0_prev_subframe; move16 ();
  450. test ();
  451. if ( sub_ex( sub_ex(tmp_lag, t0_min), 5) > 0)
  452. tmp_lag = add_ex (t0_min, 5);
  453. test ();
  454. if ( sub_ex( sub_ex(t0_max, tmp_lag), 4) > 0)
  455. tmp_lag = sub_ex (t0_max, 4);
  456. test (); test ();
  457. if ((sub_ex (lag, tmp_lag) == 0) ||
  458. (sub_ex (lag, sub_ex(tmp_lag, 1)) == 0)) {
  459. /* normal search in fractions around T0 */
  460. searchFrac (&lag, &frac, last_frac, corr, flag3);
  461. }
  462. else if (sub_ex (lag, sub_ex (tmp_lag, 2)) == 0) {
  463. test ();
  464. /* limit search around T0 to the right side */
  465. frac = 0; move16 ();
  466. searchFrac (&lag, &frac, last_frac, corr, flag3);
  467. }
  468. else if (sub_ex (lag, add_ex(tmp_lag, 1)) == 0) {
  469. test (); test ();
  470. /* limit search around T0 to the left side */
  471. last_frac = 0; move16 ();
  472. searchFrac (&lag, &frac, last_frac, corr, flag3);
  473. }
  474. else {
  475. test (); test ();
  476. /* no fractional search */
  477. frac = 0; move16 ();
  478. }
  479. }
  480. else
  481. /* test the fractions around T0 */
  482. searchFrac (&lag, &frac, last_frac, corr, flag3);
  483. }
  484. /*-----------------------------------------------------------------------*
  485. * encode pitch *
  486. *-----------------------------------------------------------------------*/
  487. test ();
  488. if (flag3 != 0) {
  489. /* flag4 indicates encoding with 4 bit resolution; */
  490. /* this is needed for mode MR475, MR515 and MR59 */
  491. flag4 = 0; move16 ();
  492. test (); test (); test (); test ();
  493. if ( (sub_ex (mode, MR475) == 0) ||
  494. (sub_ex (mode, MR515) == 0) ||
  495. (sub_ex (mode, MR59) == 0) ||
  496. (sub_ex (mode, MR67) == 0) ) {
  497. flag4 = 1; move16 ();
  498. }
  499. /* encode with 1/3 subsample resolution */
  500. *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
  501. t0_min, t0_max, delta_search, flag4); move16 (); /* function result */
  502. }
  503. else
  504. {
  505. /* encode with 1/6 subsample resolution */
  506. *ana_index = Enc_lag6(lag, frac, t0_min, delta_search); move16 (); /* function result */
  507. }
  508. /*-----------------------------------------------------------------------*
  509. * update state variables *
  510. *-----------------------------------------------------------------------*/
  511. st->T0_prev_subframe = lag; move16 ();
  512. /*-----------------------------------------------------------------------*
  513. * update output variables *
  514. *-----------------------------------------------------------------------*/
  515. *resu3 = flag3; move16 ();
  516. *pit_frac = frac; move16 ();
  517. return (lag);
  518. }