1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21 3GPP TS 26.073
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/pitch_fr.c
35 Functions:
36
37
38 Date: 02/04/2002
39
40 ------------------------------------------------------------------------------
41 REVISION HISTORY
42
43 Description: Added pOverflow as a passed in value to searchFrac and made
44 other fixes to the code regarding simple syntax fixes. Removed
45 the include of stio.h.
46
47 Description: *lag-- decrements the pointer. (*lag)-- decrements what is
48 pointed to. The latter is what the coder intended, but the former is
49 the coding instruction that was used.
50
51 Description: A common problem -- a comparison != 0 was inadvertantly replaced
52 by a comparison == 0.
53
54
55 Description: For Norm_Corr() and getRange()
56 1. Eliminated unused include files.
57 2. Replaced array addressing by pointers
58 3. Eliminated math operations that unnecessary checked for
59 saturation, in some cases this by shifting before adding and
60 in other cases by evaluating the operands
61 4. Unrolled loops to speed up processing, use decrement loops
62 5. Replaced extract_l() call with equivalent code
63 6. Modified scaling threshold and group all shifts (avoiding
64 successive shifts)
65
66 Description: Replaced OSCL mem type functions and eliminated include
67 files that now are chosen by OSCL definitions
68
69 Description: Replaced "int" and/or "char" with OSCL defined types.
70
71 Description: Removed compiler warnings.
72
73 Description:
74 ------------------------------------------------------------------------------
75 MODULE DESCRIPTION
76
77 File : pitch_fr.c
78 Purpose : Find the pitch period with 1/3 or 1/6 subsample
79 : resolution (closed loop).
80
81 ------------------------------------------------------------------------------
82 */
83
84 /*----------------------------------------------------------------------------
85 ; INCLUDES
86 ----------------------------------------------------------------------------*/
87 #include <stdlib.h>
88
89 #include "pitch_fr.h"
90 #include "oper_32b.h"
91 #include "cnst.h"
92 #include "enc_lag3.h"
93 #include "enc_lag6.h"
94 #include "inter_36.h"
95 #include "inv_sqrt.h"
96 #include "convolve.h"
97
98 #include "basic_op.h"
99
100
101 /*----------------------------------------------------------------------------
102 ; MACROS
103 ; Define module specific macros here
104 ----------------------------------------------------------------------------*/
105
106 /*----------------------------------------------------------------------------
107 ; DEFINES
108 ; Include all pre-processor statements here. Include conditional
109 ; compile variables also.
110 ----------------------------------------------------------------------------*/
111
112 /*----------------------------------------------------------------------------
113 ; LOCAL FUNCTION DEFINITIONS
114 ; Function Prototype declaration
115 ----------------------------------------------------------------------------*/
116
117 /*----------------------------------------------------------------------------
118 ; LOCAL VARIABLE DEFINITIONS
119 ; Variable declaration - defined here and used outside this module
120 ----------------------------------------------------------------------------*/
121
122 /*
123 * mode dependent parameters used in Pitch_fr()
124 * Note: order of MRxx in 'enum Mode' is important!
125 */
126 static const struct
127 {
128 Word16 max_frac_lag; /* lag up to which fractional lags are used */
129 Word16 flag3; /* enable 1/3 instead of 1/6 fract. resolution */
130 Word16 first_frac; /* first fractional to check */
131 Word16 last_frac; /* last fractional to check */
132 Word16 delta_int_low; /* integer lag below TO to start search from */
133 Word16 delta_int_range; /* integer range around T0 */
134 Word16 delta_frc_low; /* fractional below T0 */
135 Word16 delta_frc_range; /* fractional range around T0 */
136 Word16 pit_min; /* minimum pitch */
137 } mode_dep_parm[N_MODES] =
138 {
139 /* MR475 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN },
140 /* MR515 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN },
141 /* MR59 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
142 /* MR67 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
143 /* MR74 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
144 /* MR795 */ { 84, 1, -2, 2, 3, 6, 10, 19, PIT_MIN },
145 /* MR102 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
146 /* MR122 */ { 94, 0, -3, 3, 3, 6, 5, 9, PIT_MIN_MR122 }
147 };
148
149 /*
150 ------------------------------------------------------------------------------
151 FUNCTION NAME: Norm_Corr
152 ------------------------------------------------------------------------------
153 INPUT AND OUTPUT DEFINITIONS
154
155 Inputs:
156 exc[] = pointer to buffer of type Word16
157 xn[] = pointer to buffer of type Word16
158 h[] = pointer to buffer of type Word16
159 L_subfr = length of sub frame (Word16)
160 t_min = the minimum table value of type Word16
161 t_max = the maximum table value of type Word16
162 corr_norm[] = pointer to buffer of type Word16
163
164 Outputs:
165 pOverflow = 1 if the math functions called result in overflow else zero.
166
167 Returns:
168 None
169
170 Global Variables Used:
171 None
172
173 Local Variables Needed:
174 None
175
176 ------------------------------------------------------------------------------
177 FUNCTION DESCRIPTION
178
179 FUNCTION: Norm_Corr()
180
181 PURPOSE: Find the normalized correlation between the target vector
182 and the filtered past excitation.
183
184 DESCRIPTION:
185 The normalized correlation is given by the correlation between the
186 target and filtered past excitation divided by the square root of
187 the energy of filtered excitation.
188 corr[k] = <x[], y_k[]>/sqrt(y_k[],y_k[])
189 where x[] is the target vector and y_k[] is the filtered past
190 excitation at delay k.
191
192
193 ------------------------------------------------------------------------------
194 REQUIREMENTS
195
196 None
197
198 ------------------------------------------------------------------------------
199 REFERENCES
200
201 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
202
203 ------------------------------------------------------------------------------
204 PSEUDO-CODE
205
206 static void Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr,
207 Word16 t_min, Word16 t_max, Word16 corr_norm[])
208 {
209 Word16 i, j, k;
210 Word16 corr_h, corr_l, norm_h, norm_l;
211 Word32 s;
212
213 // Usally dynamic allocation of (L_subfr)
214 Word16 excf[L_SUBFR];
215 Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR];
216
217 k = -t_min;
218
219 // compute the filtered excitation for the first delay t_min
220
221 Convolve (&exc[k], h, excf, L_subfr);
222
223 // scale "excf[]" to avoid overflow
224
225 for (j = 0; j < L_subfr; j++) {
226 scaled_excf[j] = shr (excf[j], 2);
227 }
228
229 // Compute 1/sqrt(energy of excf[])
230
231 s = 0;
232 for (j = 0; j < L_subfr; j++) {
233 s = L_mac (s, excf[j], excf[j]);
234 }
235 if (L_sub (s, 67108864L) <= 0) { // if (s <= 2^26)
236 s_excf = excf;
237 h_fac = 15 - 12;
238 scaling = 0;
239 }
240 else {
241 // "excf[]" is divided by 2
242 s_excf = scaled_excf;
243 h_fac = 15 - 12 - 2;
244 scaling = 2;
245 }
246
247 // loop for every possible period
248
249 for (i = t_min; i <= t_max; i++) {
250 // Compute 1/sqrt(energy of excf[])
251
252 s = 0;
253 for (j = 0; j < L_subfr; j++) {
254 s = L_mac (s, s_excf[j], s_excf[j]);
255 }
256
257 s = Inv_sqrt (s);
258 L_Extract (s, &norm_h, &norm_l);
259
260 // Compute correlation between xn[] and excf[]
261
262 s = 0;
263 for (j = 0; j < L_subfr; j++) {
264 s = L_mac (s, xn[j], s_excf[j]);
265 }
266 L_Extract (s, &corr_h, &corr_l);
267
268 // Normalize correlation = correlation * (1/sqrt(energy))
269
270 s = Mpy_32 (corr_h, corr_l, norm_h, norm_l);
271
272 corr_norm[i] = extract_h (L_shl (s, 16));
273
274 // modify the filtered excitation excf[] for the next iteration
275
276 if (sub (i, t_max) != 0) {
277 k--;
278 for (j = L_subfr - 1; j > 0; j--) {
279 s = L_mult (exc[k], h[j]);
280 s = L_shl (s, h_fac);
281 s_excf[j] = add (extract_h (s), s_excf[j - 1]);
282 }
283 s_excf[0] = shr (exc[k], scaling);
284 }
285 }
286 return;
287 }
288
289 ------------------------------------------------------------------------------
290 RESOURCES USED [optional]
291
292 When the code is written for a specific target processor the
293 the resources used should be documented below.
294
295 HEAP MEMORY USED: x bytes
296
297 STACK MEMORY USED: x bytes
298
299 CLOCK CYCLES: (cycle count equation for this function) + (variable
300 used to represent cycle count for each subroutine
301 called)
302 where: (cycle count variable) = cycle count for [subroutine
303 name]
304
305 ------------------------------------------------------------------------------
306 CAUTION [optional]
307 [State any special notes, constraints or cautions for users of this function]
308
309 ------------------------------------------------------------------------------
310 */
311
Norm_Corr(Word16 exc[],Word16 xn[],Word16 h[],Word16 L_subfr,Word16 t_min,Word16 t_max,Word16 corr_norm[],Flag * pOverflow)312 static void Norm_Corr(Word16 exc[],
313 Word16 xn[],
314 Word16 h[],
315 Word16 L_subfr,
316 Word16 t_min,
317 Word16 t_max,
318 Word16 corr_norm[],
319 Flag *pOverflow)
320 {
321 Word16 i;
322 Word16 j;
323 Word16 k;
324 Word16 corr_h;
325 Word16 corr_l;
326 Word16 norm_h;
327 Word16 norm_l;
328 Word32 s;
329 Word32 mul;
330 Word32 s2;
331 Word16 excf[L_SUBFR];
332 Word16 scaling;
333 Word16 h_fac;
334 Word16 *s_excf;
335 Word16 scaled_excf[L_SUBFR];
336 Word16 *p_s_excf;
337 Word16 *p_excf;
338 Word16 temp;
339 Word16 *p_x;
340 Word16 *p_h;
341
342 k = -t_min;
343
344 /* compute the filtered excitation for the first delay t_min */
345
346 Convolve(&exc[k], h, excf, L_subfr);
347
348 /* scale "excf[]" to avoid overflow */
349 s = 0;
350 p_s_excf = scaled_excf;
351 p_excf = excf;
352
353 for (j = (L_subfr >> 1); j != 0; j--)
354 {
355 temp = *(p_excf++);
356 *(p_s_excf++) = temp >> 2;
357 __builtin_mul_overflow(temp, temp, &mul);
358 __builtin_add_overflow(s, mul, &s);
359 temp = *(p_excf++);
360 *(p_s_excf++) = temp >> 2;
361 __builtin_mul_overflow(temp, temp, &mul);
362 __builtin_add_overflow(s, mul, &s);
363 }
364
365
366 if (s <= (67108864L >> 1))
367 {
368 s_excf = excf;
369 h_fac = 12;
370 scaling = 0;
371 }
372 else
373 {
374 /* "excf[]" is divided by 2 */
375 s_excf = scaled_excf;
376 h_fac = 14;
377 scaling = 2;
378 }
379
380 /* loop for every possible period */
381
382 for (i = t_min; i <= t_max; i++)
383 {
384 /* Compute 1/sqrt(energy of excf[]) */
385
386 s = s2 = 0;
387 p_x = xn;
388 p_s_excf = s_excf;
389 j = L_subfr >> 1;
390
391 while (j--)
392 {
393 __builtin_mul_overflow(*(p_x++), *p_s_excf, &mul);
394 __builtin_add_overflow(s, mul, &s);
395 __builtin_mul_overflow(*p_s_excf, *p_s_excf, &mul);
396 __builtin_add_overflow(s2, mul, &s2);
397 p_s_excf++;
398 __builtin_mul_overflow(*(p_x++), *p_s_excf, &mul);
399 __builtin_add_overflow(s, mul, &s);
400 __builtin_mul_overflow(*p_s_excf, *p_s_excf, &mul);
401 __builtin_add_overflow(s2, mul, &s2);
402 p_s_excf++;
403 }
404
405 s2 = s2 << 1;
406 s2 = Inv_sqrt(s2, pOverflow);
407 norm_h = (Word16)(s2 >> 16);
408 __builtin_sub_overflow((s2 >> 1), (norm_h << 15), &norm_l);
409 corr_h = (Word16)(s >> 15);
410 __builtin_sub_overflow(s, (corr_h << 15), &corr_l);
411
412 /* Normalize correlation = correlation * (1/sqrt(energy)) */
413
414 s = Mpy_32(corr_h, corr_l, norm_h, norm_l, pOverflow);
415
416 corr_norm[i] = (Word16) s ;
417
418 /* modify the filtered excitation excf[] for the next iteration */
419 if (i != t_max)
420 {
421 k--;
422 temp = exc[k];
423 p_s_excf = &s_excf[L_subfr - 1];
424 p_h = &h[L_subfr - 1];
425
426 p_excf = &s_excf[L_subfr - 2];
427 for (j = (L_subfr - 1) >> 1; j != 0; j--)
428 {
429 s = ((Word32) temp * *(p_h--)) >> h_fac;
430 *(p_s_excf--) = (Word16) s + *(p_excf--);
431 s = ((Word32) temp * *(p_h--)) >> h_fac;
432 *(p_s_excf--) = (Word16) s + *(p_excf--);
433 }
434
435 s = ((Word32) temp * *(p_h)) >> h_fac;
436 *(p_s_excf--) = (Word16) s + *(p_excf);
437
438 *(p_s_excf) = temp >> scaling;
439 }
440
441 }
442 return;
443 }
444
445 /****************************************************************************/
446
447
448 /*
449 ------------------------------------------------------------------------------
450 FUNCTION NAME: searchFrac
451 ------------------------------------------------------------------------------
452 INPUT AND OUTPUT DEFINITIONS
453
454 Inputs:
455 lag = pointer to integer pitch of type Word16
456 frac = pointer to starting point of search fractional pitch of type Word16
457 last_frac = endpoint of search of type Word16
458 corr[] = pointer to normalized correlation of type Word16
459 flag3 = subsample resolution (3: =1 / 6: =0) of type Word16
460
461 Outputs:
462 None
463
464 Returns:
465 None
466
467 Global Variables Used:
468 None
469
470 Local Variables Needed:
471 None
472
473 ------------------------------------------------------------------------------
474 FUNCTION DESCRIPTION
475
476 FUNCTION: searchFrac()
477
478 PURPOSE: Find fractional pitch
479
480 DESCRIPTION:
481 The function interpolates the normalized correlation at the
482 fractional positions around lag T0. The position at which the
483 interpolation function reaches its maximum is the fractional pitch.
484 Starting point of the search is frac, end point is last_frac.
485 frac is overwritten with the fractional pitch.
486
487 ------------------------------------------------------------------------------
488 REQUIREMENTS
489
490 None
491
492 ------------------------------------------------------------------------------
493 REFERENCES
494
495 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
496
497 ------------------------------------------------------------------------------
498 PSEUDO-CODE
499
500 static void searchFrac (
501 Word16 *lag, // i/o : integer pitch
502 Word16 *frac, // i/o : start point of search -
503 fractional pitch
504 Word16 last_frac, // i : endpoint of search
505 Word16 corr[], // i : normalized correlation
506 Word16 flag3 // i : subsample resolution
507 (3: =1 / 6: =0)
508 )
509 {
510 Word16 i;
511 Word16 max;
512 Word16 corr_int;
513
514 // Test the fractions around T0 and choose the one which maximizes
515 // the interpolated normalized correlation.
516
517 max = Interpol_3or6 (&corr[*lag], *frac, flag3); // function result
518
519 for (i = add (*frac, 1); i <= last_frac; i++) {
520 corr_int = Interpol_3or6 (&corr[*lag], i, flag3);
521 if (sub (corr_int, max) > 0) {
522 max = corr_int;
523 *frac = i;
524 }
525 }
526
527 if (flag3 == 0) {
528 // Limit the fraction value in the interval [-2,-1,0,1,2,3]
529
530 if (sub (*frac, -3) == 0) {
531 *frac = 3;
532 *lag = sub (*lag, 1);
533 }
534 }
535 else {
536 // limit the fraction value between -1 and 1
537
538 if (sub (*frac, -2) == 0) {
539 *frac = 1;
540 *lag = sub (*lag, 1);
541 }
542 if (sub (*frac, 2) == 0) {
543 *frac = -1;
544 *lag = add (*lag, 1);
545 }
546 }
547 }
548
549 ------------------------------------------------------------------------------
550 RESOURCES USED [optional]
551
552 When the code is written for a specific target processor the
553 the resources used should be documented below.
554
555 HEAP MEMORY USED: x bytes
556
557 STACK MEMORY USED: x bytes
558
559 CLOCK CYCLES: (cycle count equation for this function) + (variable
560 used to represent cycle count for each subroutine
561 called)
562 where: (cycle count variable) = cycle count for [subroutine
563 name]
564
565 ------------------------------------------------------------------------------
566 CAUTION [optional]
567 [State any special notes, constraints or cautions for users of this function]
568
569 ------------------------------------------------------------------------------
570 */
571
searchFrac(Word16 * lag,Word16 * frac,Word16 last_frac,Word16 corr[],Word16 flag3,Flag * pOverflow,enum Mode mode)572 static void searchFrac(
573 Word16 *lag, /* i/o : integer pitch */
574 Word16 *frac, /* i/o : start point of search -
575 fractional pitch */
576 Word16 last_frac, /* i : endpoint of search */
577 Word16 corr[], /* i : normalized correlation */
578 Word16 flag3, /* i : subsample resolution
579 (3: =1 / 6: =0) */
580 Flag *pOverflow,
581 enum Mode mode
582 )
583 {
584 Word16 i;
585 Word16 max;
586 Word16 corr_int;
587 Word16 minPitch;
588
589 /* Test the fractions around T0 and choose the one which maximizes */
590 /* the interpolated normalized correlation. */
591
592 max = Interpol_3or6(&corr[*lag], *frac, flag3, pOverflow);
593 /* function result */
594
595 for (i = *frac + 1; i <= last_frac; i++)
596 {
597 corr_int = Interpol_3or6(&corr[*lag], i, flag3, pOverflow);
598 if (corr_int > max)
599 {
600 max = corr_int;
601 *frac = i;
602 }
603 }
604
605 minPitch = (mode == MR122) ? PIT_MIN_MR122 : PIT_MIN;
606 if (flag3 == 0)
607 {
608 /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */
609
610 if (*frac == -3)
611 {
612 if (*lag > minPitch)
613 {
614 *frac = 3;
615 (*lag)--;
616 }
617 else
618 {
619 *frac = -2;
620 }
621 }
622 }
623 else
624 {
625 /* limit the fraction value between -1 and 1 */
626
627 if (*frac == -2)
628 {
629 if (*lag > minPitch)
630 {
631 *frac = 1;
632 (*lag)--;
633 }
634 else
635 {
636 *frac = -1;
637 }
638 }
639 else if (*frac == 2)
640 {
641 if (*lag < PIT_MAX)
642 {
643 *frac = -1;
644 (*lag)++;
645 }
646 else
647 {
648 *frac = 1;
649 }
650 }
651 }
652 }
653
654 /****************************************************************************/
655
656
657 /*
658 ------------------------------------------------------------------------------
659 FUNCTION NAME: getRange
660 ------------------------------------------------------------------------------
661 INPUT AND OUTPUT DEFINITIONS
662
663 Inputs:
664 T0 = integer pitch of type Word16
665 delta_low = search start offset of type Word16
666 delta_range = search range of type Word16
667 pitmin = minimum pitch of type Word16
668 pitmax = maximum pitch of type Word16
669 t0_min = search range minimum of type Word16
670 t0_max = search range maximum of type Word16
671
672 Outputs:
673 pOverflow = 1 if the math functions called result in overflow else zero.
674
675 Returns:
676 None
677
678 Global Variables Used:
679 None
680
681 Local Variables Needed:
682 None
683
684 ------------------------------------------------------------------------------
685 FUNCTION DESCRIPTION
686
687 FUNCTION: getRange()
688
689 PURPOSE: Sets range around open-loop pitch or integer pitch of last subframe
690
691 DESCRIPTION:
692 Takes integer pitch T0 and calculates a range around it with
693 t0_min = T0-delta_low and t0_max = (T0-delta_low) + delta_range
694 t0_min and t0_max are bounded by pitmin and pitmax
695 ------------------------------------------------------------------------------
696 REQUIREMENTS
697
698 None
699
700 ------------------------------------------------------------------------------
701 REFERENCES
702
703 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
704
705 ------------------------------------------------------------------------------
706 PSEUDO-CODE
707
708 static void getRange (
709 Word16 T0, // i : integer pitch
710 Word16 delta_low, // i : search start offset
711 Word16 delta_range, // i : search range
712 Word16 pitmin, // i : minimum pitch
713 Word16 pitmax, // i : maximum pitch
714 Word16 *t0_min, // o : search range minimum
715 Word16 *t0_max) // o : search range maximum
716 {
717 *t0_min = sub(T0, delta_low);
718 if (sub(*t0_min, pitmin) < 0) {
719 *t0_min = pitmin;
720 }
721 *t0_max = add(*t0_min, delta_range);
722 if (sub(*t0_max, pitmax) > 0) {
723 *t0_max = pitmax;
724 *t0_min = sub(*t0_max, delta_range);
725 }
726 }
727
728 ------------------------------------------------------------------------------
729 RESOURCES USED [optional]
730
731 When the code is written for a specific target processor the
732 the resources used should be documented below.
733
734 HEAP MEMORY USED: x bytes
735
736 STACK MEMORY USED: x bytes
737
738 CLOCK CYCLES: (cycle count equation for this function) + (variable
739 used to represent cycle count for each subroutine
740 called)
741 where: (cycle count variable) = cycle count for [subroutine
742 name]
743
744 ------------------------------------------------------------------------------
745 CAUTION [optional]
746 [State any special notes, constraints or cautions for users of this function]
747
748 ------------------------------------------------------------------------------
749 */
getRange(Word16 T0,Word16 delta_low,Word16 delta_range,Word16 pitmin,Word16 pitmax,Word16 * t0_min,Word16 * t0_max,Flag * pOverflow)750 static void getRange(
751 Word16 T0, /* i : integer pitch */
752 Word16 delta_low, /* i : search start offset */
753 Word16 delta_range, /* i : search range */
754 Word16 pitmin, /* i : minimum pitch */
755 Word16 pitmax, /* i : maximum pitch */
756 Word16 *t0_min, /* o : search range minimum */
757 Word16 *t0_max, /* o : search range maximum */
758 Flag *pOverflow)
759 {
760
761 Word16 temp;
762 OSCL_UNUSED_ARG(pOverflow);
763
764 temp = *t0_min;
765 temp = T0 - delta_low;
766 if (temp < pitmin)
767 {
768 temp = pitmin;
769 }
770 *t0_min = temp;
771
772 temp += delta_range;
773 if (temp > pitmax)
774 {
775 temp = pitmax;
776 *t0_min = pitmax - delta_range;
777 }
778 *t0_max = temp;
779
780 }
781
782
783 /****************************************************************************/
784
785
786 /*
787 ------------------------------------------------------------------------------
788 FUNCTION NAME: Pitch_fr_init
789 ------------------------------------------------------------------------------
790 INPUT AND OUTPUT DEFINITIONS
791
792 Inputs:
793 state = pointer to a pointer of structure type Pitch_fr_State.
794
795 Outputs:
796 None
797
798 Returns:
799 Returns a zero if successful and -1 if not successful.
800
801 Global Variables Used:
802 None
803
804 Local Variables Needed:
805 None
806
807 ------------------------------------------------------------------------------
808 FUNCTION DESCRIPTION
809
810 Function: Pitch_fr_init
811 Purpose: Allocates state memory and initializes state memory
812
813 ------------------------------------------------------------------------------
814 REQUIREMENTS
815
816 None
817
818 ------------------------------------------------------------------------------
819 REFERENCES
820
821 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
822
823 ------------------------------------------------------------------------------
824 PSEUDO-CODE
825
826 int Pitch_fr_init (Pitch_frState **state)
827 {
828 Pitch_frState* s;
829
830 if (state == (Pitch_frState **) NULL){
831 // fprintf(stderr, "Pitch_fr_init: invalid parameter\n");
832 return -1;
833 }
834 *state = NULL;
835
836 // allocate memory
837 if ((s= (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL){
838 // fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n");
839 return -1;
840 }
841
842 Pitch_fr_reset(s);
843 *state = s;
844
845 return 0;
846 }
847
848 ------------------------------------------------------------------------------
849 RESOURCES USED [optional]
850
851 When the code is written for a specific target processor the
852 the resources used should be documented below.
853
854 HEAP MEMORY USED: x bytes
855
856 STACK MEMORY USED: x bytes
857
858 CLOCK CYCLES: (cycle count equation for this function) + (variable
859 used to represent cycle count for each subroutine
860 called)
861 where: (cycle count variable) = cycle count for [subroutine
862 name]
863
864 ------------------------------------------------------------------------------
865 CAUTION [optional]
866 [State any special notes, constraints or cautions for users of this function]
867
868 ------------------------------------------------------------------------------
869 */
Pitch_fr_init(Pitch_frState ** state)870 Word16 Pitch_fr_init(Pitch_frState **state)
871 {
872 Pitch_frState* s;
873
874 if (state == (Pitch_frState **) NULL)
875 {
876 /* fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); */
877 return -1;
878 }
879 *state = NULL;
880
881 /* allocate memory */
882 if ((s = (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL)
883 {
884 /* fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n"); */
885 return -1;
886 }
887
888 Pitch_fr_reset(s);
889 *state = s;
890
891 return 0;
892 }
893
894
895 /****************************************************************************/
896
897
898 /*
899 ------------------------------------------------------------------------------
900 FUNCTION NAME: Pitch_fr_reset
901 ------------------------------------------------------------------------------
902 INPUT AND OUTPUT DEFINITIONS
903
904 Inputs:
905 state = pointer to a pointer of structure type Pitch_fr_State.
906
907 Outputs:
908 None
909
910 Returns:
911 Returns a zero if successful and -1 if not successful.
912
913 Global Variables Used:
914 None
915
916 Local Variables Needed:
917 None
918
919 ------------------------------------------------------------------------------
920 FUNCTION DESCRIPTION
921
922 Function: Pitch_fr_reset
923 Purpose: Initializes state memory to zero
924
925 ------------------------------------------------------------------------------
926 REQUIREMENTS
927
928 None
929
930 ------------------------------------------------------------------------------
931 REFERENCES
932
933 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
934
935 ------------------------------------------------------------------------------
936 PSEUDO-CODE
937
938 int Pitch_fr_reset (Pitch_frState *state)
939 {
940
941 if (state == (Pitch_frState *) NULL){
942 // fprintf(stderr, "Pitch_fr_reset: invalid parameter\n");
943 return -1;
944 }
945
946 state->T0_prev_subframe = 0;
947
948 return 0;
949 }
950
951 ------------------------------------------------------------------------------
952 RESOURCES USED [optional]
953
954 When the code is written for a specific target processor the
955 the resources used should be documented below.
956
957 HEAP MEMORY USED: x bytes
958
959 STACK MEMORY USED: x bytes
960
961 CLOCK CYCLES: (cycle count equation for this function) + (variable
962 used to represent cycle count for each subroutine
963 called)
964 where: (cycle count variable) = cycle count for [subroutine
965 name]
966
967 ------------------------------------------------------------------------------
968 CAUTION [optional]
969 [State any special notes, constraints or cautions for users of this function]
970
971 ------------------------------------------------------------------------------
972 */
Pitch_fr_reset(Pitch_frState * state)973 Word16 Pitch_fr_reset(Pitch_frState *state)
974 {
975
976 if (state == (Pitch_frState *) NULL)
977 {
978 /* fprintf(stderr, "Pitch_fr_reset: invalid parameter\n"); */
979 return -1;
980 }
981
982 state->T0_prev_subframe = 0;
983
984 return 0;
985 }
986
987
988 /****************************************************************************/
989
990
991 /*
992 ------------------------------------------------------------------------------
993 FUNCTION NAME: Pitch_fr_exit
994 ------------------------------------------------------------------------------
995 INPUT AND OUTPUT DEFINITIONS
996
997 Inputs:
998 state = pointer to a pointer of structure type Pitch_fr_State.
999
1000 Outputs:
1001 None
1002
1003 Returns:
1004 None
1005
1006 Global Variables Used:
1007 None
1008
1009 Local Variables Needed:
1010 None
1011
1012 ------------------------------------------------------------------------------
1013 FUNCTION DESCRIPTION
1014
1015 Function: Pitch_fr_exit
1016 Purpose: The memory for state is freed.
1017
1018 ------------------------------------------------------------------------------
1019 REQUIREMENTS
1020
1021 None
1022
1023 ------------------------------------------------------------------------------
1024 REFERENCES
1025
1026 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1027
1028 ------------------------------------------------------------------------------
1029 PSEUDO-CODE
1030
1031 void Pitch_fr_exit (Pitch_frState **state)
1032 {
1033 if (state == NULL || *state == NULL)
1034 return;
1035
1036 // deallocate memory
1037 free(*state);
1038 *state = NULL;
1039
1040 return;
1041 }
1042
1043 ------------------------------------------------------------------------------
1044 RESOURCES USED [optional]
1045
1046 When the code is written for a specific target processor the
1047 the resources used should be documented below.
1048
1049 HEAP MEMORY USED: x bytes
1050
1051 STACK MEMORY USED: x bytes
1052
1053 CLOCK CYCLES: (cycle count equation for this function) + (variable
1054 used to represent cycle count for each subroutine
1055 called)
1056 where: (cycle count variable) = cycle count for [subroutine
1057 name]
1058
1059 ------------------------------------------------------------------------------
1060 CAUTION [optional]
1061 [State any special notes, constraints or cautions for users of this function]
1062
1063 ------------------------------------------------------------------------------
1064 */
Pitch_fr_exit(Pitch_frState ** state)1065 void Pitch_fr_exit(Pitch_frState **state)
1066 {
1067 if (state == NULL || *state == NULL)
1068 return;
1069
1070 /* deallocate memory */
1071 free(*state);
1072 *state = NULL;
1073
1074 return;
1075 }
1076
1077 /****************************************************************************/
1078
1079
1080 /*
1081 ------------------------------------------------------------------------------
1082 FUNCTION NAME: Pitch_fr
1083 ------------------------------------------------------------------------------
1084 INPUT AND OUTPUT DEFINITIONS
1085
1086 Inputs:
1087 st = pointer to stat structure of type Pitch_frState
1088 mode = codec mode of type enum Mode
1089 T_op[] = pointer to open loop pitch lags of type Word16
1090 exc[] = pointer to excitation buffer of type Word16
1091 xn[] = pointer to target vector of type Word16
1092 h[] = pointer to impulse response of synthesis and weighting filters
1093 of type Word16
1094 L_subfr = length of subframe of type Word16
1095 i_subfr = subframe offset of type Word16
1096
1097 Outputs:
1098 pit_frac = pointer to pitch period (fractional) of type Word16
1099 resu3 = pointer to subsample resolution of type Word16
1100 ana_index = pointer to index of encoding of type Word16
1101
1102 Returns:
1103 None
1104
1105 Global Variables Used:
1106 None
1107
1108 Local Variables Needed:
1109 None
1110
1111 ------------------------------------------------------------------------------
1112 FUNCTION DESCRIPTION
1113
1114 FUNCTION: Pitch_fr()
1115
1116 PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution
1117 (closed loop).
1118
1119 DESCRIPTION:
1120 - find the normalized correlation between the target and filtered
1121 past excitation in the search range.
1122 - select the delay with maximum normalized correlation.
1123 - interpolate the normalized correlation at fractions -3/6 to 3/6
1124 with step 1/6 around the chosen delay.
1125 - The fraction which gives the maximum interpolated value is chosen.
1126
1127 ------------------------------------------------------------------------------
1128 REQUIREMENTS
1129
1130 None
1131
1132 ------------------------------------------------------------------------------
1133 REFERENCES
1134
1135 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1136
1137 ------------------------------------------------------------------------------
1138 PSEUDO-CODE
1139
1140 Word16 Pitch_fr ( // o : pitch period (integer)
1141 Pitch_frState *st, // i/o : State struct
1142 enum Mode mode, // i : codec mode
1143 Word16 T_op[], // i : open loop pitch lags
1144 Word16 exc[], // i : excitation buffer Q0
1145 Word16 xn[], // i : target vector Q0
1146 Word16 h[], // i : impulse response of synthesis and
1147 weighting filters Q12
1148 Word16 L_subfr, // i : Length of subframe
1149 Word16 i_subfr, // i : subframe offset
1150 Word16 *pit_frac, // o : pitch period (fractional)
1151 Word16 *resu3, // o : subsample resolution 1/3 (=1) or 1/6 (=0)
1152 Word16 *ana_index // o : index of encoding
1153 )
1154 {
1155 Word16 i;
1156 Word16 t_min, t_max;
1157 Word16 t0_min, t0_max;
1158 Word16 max, lag, frac;
1159 Word16 tmp_lag;
1160 Word16 *corr;
1161 Word16 corr_v[40]; // Total length = t0_max-t0_min+1+2*L_INTER_SRCH
1162
1163 Word16 max_frac_lag;
1164 Word16 flag3, flag4;
1165 Word16 last_frac;
1166 Word16 delta_int_low, delta_int_range;
1167 Word16 delta_frc_low, delta_frc_range;
1168 Word16 pit_min;
1169 Word16 frame_offset;
1170 Word16 delta_search;
1171
1172 //-----------------------------------------------------------------------
1173 // set mode specific variables
1174 //----------------------------------------------------------------------
1175
1176 max_frac_lag = mode_dep_parm[mode].max_frac_lag;
1177 flag3 = mode_dep_parm[mode].flag3;
1178 frac = mode_dep_parm[mode].first_frac;
1179 last_frac = mode_dep_parm[mode].last_frac;
1180 delta_int_low = mode_dep_parm[mode].delta_int_low;
1181 delta_int_range = mode_dep_parm[mode].delta_int_range;
1182
1183 delta_frc_low = mode_dep_parm[mode].delta_frc_low;
1184 delta_frc_range = mode_dep_parm[mode].delta_frc_range;
1185 pit_min = mode_dep_parm[mode].pit_min;
1186
1187 //-----------------------------------------------------------------------
1188 // decide upon full or differential search
1189 //-----------------------------------------------------------------------
1190
1191 delta_search = 1;
1192
1193 if ((i_subfr == 0) || (sub(i_subfr,L_FRAME_BY2) == 0)) {
1194
1195 // Subframe 1 and 3
1196
1197 if (((sub((Word16)mode, (Word16)MR475) != 0) && (sub((Word16)mode,
1198 (Word16)MR515) != 0)) ||
1199 (sub(i_subfr,L_FRAME_BY2) != 0)) {
1200
1201 // set t0_min, t0_max for full search
1202 // this is *not* done for mode MR475, MR515 in subframe 3
1203
1204 delta_search = 0; // no differential search
1205
1206 // calculate index into T_op which contains the open-loop
1207 // pitch estimations for the 2 big subframes
1208
1209 frame_offset = 1;
1210 if (i_subfr == 0)
1211 frame_offset = 0;
1212
1213 // get T_op from the corresponding half frame and
1214 // set t0_min, t0_max
1215
1216 getRange (T_op[frame_offset], delta_int_low, delta_int_range,
1217 pit_min, PIT_MAX, &t0_min, &t0_max);
1218 }
1219 else {
1220
1221 // mode MR475, MR515 and 3. Subframe: delta search as well
1222 getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1223 pit_min, PIT_MAX, &t0_min, &t0_max);
1224 }
1225 }
1226 else {
1227
1228 // for Subframe 2 and 4
1229 // get range around T0 of previous subframe for delta search
1230
1231 getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1232 pit_min, PIT_MAX, &t0_min, &t0_max);
1233 }
1234
1235 //-----------------------------------------------------------------------
1236 Find interval to compute normalized correlation
1237 -----------------------------------------------------------------------
1238
1239 t_min = sub (t0_min, L_INTER_SRCH);
1240 t_max = add (t0_max, L_INTER_SRCH);
1241
1242 corr = &corr_v[-t_min];
1243
1244 //-----------------------------------------------------------------------
1245 Compute normalized correlation between target and filtered excitation
1246 -----------------------------------------------------------------------
1247
1248 Norm_Corr (exc, xn, h, L_subfr, t_min, t_max, corr);
1249
1250 //-----------------------------------------------------------------------
1251 Find integer pitch
1252 -----------------------------------------------------------------------
1253
1254 max = corr[t0_min];
1255 lag = t0_min;
1256
1257 for (i = t0_min + 1; i <= t0_max; i++) {
1258 if (sub (corr[i], max) >= 0) {
1259 max = corr[i];
1260 lag = i;
1261 }
1262 }
1263
1264 //-----------------------------------------------------------------------
1265 Find fractional pitch
1266 -----------------------------------------------------------------------
1267 if ((delta_search == 0) && (sub (lag, max_frac_lag) > 0)) {
1268
1269 // full search and integer pitch greater than max_frac_lag
1270 // fractional search is not needed, set fractional to zero
1271
1272 frac = 0;
1273 }
1274 else {
1275
1276 // if differential search AND mode MR475 OR MR515 OR MR59 OR MR67
1277 // then search fractional with 4 bits resolution
1278
1279 if ((delta_search != 0) &&
1280 ((sub ((Word16)mode, (Word16)MR475) == 0) ||
1281 (sub ((Word16)mode, (Word16)MR515) == 0) ||
1282 (sub ((Word16)mode, (Word16)MR59) == 0) ||
1283 (sub ((Word16)mode, (Word16)MR67) == 0))) {
1284
1285 // modify frac or last_frac according to position of last
1286 // integer pitch: either search around integer pitch,
1287 // or only on left or right side
1288
1289 tmp_lag = st->T0_prev_subframe;
1290 if ( sub( sub(tmp_lag, t0_min), 5) > 0)
1291 tmp_lag = add (t0_min, 5);
1292 if ( sub( sub(t0_max, tmp_lag), 4) > 0)
1293 tmp_lag = sub (t0_max, 4);
1294
1295 if ((sub (lag, tmp_lag) == 0) ||
1296 (sub (lag, sub(tmp_lag, 1)) == 0)) {
1297
1298 // normal search in fractions around T0
1299
1300 searchFrac (&lag, &frac, last_frac, corr, flag3);
1301
1302 }
1303 else if (sub (lag, sub (tmp_lag, 2)) == 0) {
1304 // limit search around T0 to the right side
1305 frac = 0;
1306 searchFrac (&lag, &frac, last_frac, corr, flag3);
1307 }
1308 else if (sub (lag, add(tmp_lag, 1)) == 0) {
1309 // limit search around T0 to the left side
1310 last_frac = 0;
1311 searchFrac (&lag, &frac, last_frac, corr, flag3);
1312 }
1313 else {
1314 // no fractional search
1315 frac = 0;
1316 }
1317 }
1318 else
1319 // test the fractions around T0
1320 searchFrac (&lag, &frac, last_frac, corr, flag3);
1321 }
1322
1323 //-----------------------------------------------------------------------
1324 // encode pitch
1325 //-----------------------------------------------------------------------
1326
1327 if (flag3 != 0) {
1328 // flag4 indicates encoding with 4 bit resolution;
1329 // this is needed for mode MR475, MR515 and MR59
1330
1331 flag4 = 0;
1332 if ( (sub ((Word16)mode, (Word16)MR475) == 0) ||
1333 (sub ((Word16)mode, (Word16)MR515) == 0) ||
1334 (sub ((Word16)mode, (Word16)MR59) == 0) ||
1335 (sub ((Word16)mode, (Word16)MR67) == 0) ) {
1336 flag4 = 1;
1337 }
1338
1339 // encode with 1/3 subsample resolution
1340
1341 *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
1342 t0_min, t0_max, delta_search, flag4);
1343 // function result
1344
1345 }
1346 else
1347 {
1348 // encode with 1/6 subsample resolution
1349
1350 *ana_index = Enc_lag6(lag, frac, t0_min, delta_search);
1351 // function result
1352 }
1353
1354 //-----------------------------------------------------------------------
1355 // update state variables
1356 //-----------------------------------------------------------------------
1357
1358 st->T0_prev_subframe = lag;
1359
1360 //-----------------------------------------------------------------------
1361 // update output variables
1362 //-----------------------------------------------------------------------
1363
1364 *resu3 = flag3;
1365
1366 *pit_frac = frac;
1367
1368 return (lag);
1369 }
1370
1371
1372 ------------------------------------------------------------------------------
1373 RESOURCES USED [optional]
1374
1375 When the code is written for a specific target processor the
1376 the resources used should be documented below.
1377
1378 HEAP MEMORY USED: x bytes
1379
1380 STACK MEMORY USED: x bytes
1381
1382 CLOCK CYCLES: (cycle count equation for this function) + (variable
1383 used to represent cycle count for each subroutine
1384 called)
1385 where: (cycle count variable) = cycle count for [subroutine
1386 name]
1387
1388 ------------------------------------------------------------------------------
1389 CAUTION [optional]
1390 [State any special notes, constraints or cautions for users of this function]
1391
1392 ------------------------------------------------------------------------------
1393 */
Pitch_fr(Pitch_frState * st,enum Mode mode,Word16 T_op[],Word16 exc[],Word16 xn[],Word16 h[],Word16 L_subfr,Word16 i_subfr,Word16 * pit_frac,Word16 * resu3,Word16 * ana_index,Flag * pOverflow)1394 Word16 Pitch_fr( /* o : pitch period (integer) */
1395 Pitch_frState *st, /* i/o : State struct */
1396 enum Mode mode, /* i : codec mode */
1397 Word16 T_op[], /* i : open loop pitch lags */
1398 Word16 exc[], /* i : excitation buffer Q0 */
1399 Word16 xn[], /* i : target vector Q0 */
1400 Word16 h[], /* i : impulse response of synthesis and
1401 weighting filters Q12 */
1402 Word16 L_subfr, /* i : Length of subframe */
1403 Word16 i_subfr, /* i : subframe offset */
1404 Word16 *pit_frac, /* o : pitch period (fractional) */
1405 Word16 *resu3, /* o : subsample resolution 1/3 (=1) or 1/6 (=0) */
1406 Word16 *ana_index, /* o : index of encoding */
1407 Flag *pOverflow
1408 )
1409 {
1410 Word16 i;
1411 Word16 t_min;
1412 Word16 t_max;
1413 Word16 t0_min = 0;
1414 Word16 t0_max;
1415 Word16 max;
1416 Word16 lag;
1417 Word16 frac;
1418 Word16 tmp_lag;
1419 Word16 *corr;
1420 Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */
1421
1422 Word16 max_frac_lag;
1423 Word16 flag3;
1424 Word16 flag4;
1425 Word16 last_frac;
1426 Word16 delta_int_low;
1427 Word16 delta_int_range;
1428 Word16 delta_frc_low;
1429 Word16 delta_frc_range;
1430 Word16 pit_min;
1431 Word16 frame_offset;
1432 Word16 delta_search;
1433
1434 /*-----------------------------------------------------------------------*
1435 * set mode specific variables *
1436 *-----------------------------------------------------------------------*/
1437
1438 max_frac_lag = mode_dep_parm[mode].max_frac_lag;
1439 flag3 = mode_dep_parm[mode].flag3;
1440 frac = mode_dep_parm[mode].first_frac;
1441 last_frac = mode_dep_parm[mode].last_frac;
1442 delta_int_low = mode_dep_parm[mode].delta_int_low;
1443 delta_int_range = mode_dep_parm[mode].delta_int_range;
1444
1445 delta_frc_low = mode_dep_parm[mode].delta_frc_low;
1446 delta_frc_range = mode_dep_parm[mode].delta_frc_range;
1447 pit_min = mode_dep_parm[mode].pit_min;
1448
1449 /*-----------------------------------------------------------------------*
1450 * decide upon full or differential search *
1451 *-----------------------------------------------------------------------*/
1452
1453 delta_search = 1;
1454
1455 if ((i_subfr == 0) || (i_subfr == L_FRAME_BY2))
1456 {
1457
1458 /* Subframe 1 and 3 */
1459
1460 if (((mode != MR475) && (mode != MR515)) || (i_subfr != L_FRAME_BY2))
1461 {
1462
1463 /* set t0_min, t0_max for full search */
1464 /* this is *not* done for mode MR475, MR515 in subframe 3 */
1465
1466 delta_search = 0; /* no differential search */
1467
1468 /* calculate index into T_op which contains the open-loop */
1469 /* pitch estimations for the 2 big subframes */
1470
1471 frame_offset = 1;
1472 if (i_subfr == 0)
1473 frame_offset = 0;
1474
1475 /* get T_op from the corresponding half frame and */
1476 /* set t0_min, t0_max */
1477
1478 getRange(T_op[frame_offset], delta_int_low, delta_int_range,
1479 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1480 }
1481 else
1482 {
1483
1484 /* mode MR475, MR515 and 3. Subframe: delta search as well */
1485 getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1486 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1487 }
1488 }
1489 else
1490 {
1491
1492 /* for Subframe 2 and 4 */
1493 /* get range around T0 of previous subframe for delta search */
1494
1495 getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1496 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1497 }
1498
1499 /*-----------------------------------------------------------------------*
1500 * Find interval to compute normalized correlation *
1501 *-----------------------------------------------------------------------*/
1502
1503 t_min = sub(t0_min, L_INTER_SRCH, pOverflow);
1504 t_max = add(t0_max, L_INTER_SRCH, pOverflow);
1505
1506 corr = &corr_v[-t_min];
1507
1508 /*-----------------------------------------------------------------------*
1509 * Compute normalized correlation between target and filtered excitation *
1510 *-----------------------------------------------------------------------*/
1511
1512 Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr, pOverflow);
1513
1514 /*-----------------------------------------------------------------------*
1515 * Find integer pitch *
1516 *-----------------------------------------------------------------------*/
1517
1518 max = corr[t0_min];
1519 lag = t0_min;
1520
1521 for (i = t0_min + 1; i <= t0_max; i++)
1522 {
1523 if (corr[i] >= max)
1524 {
1525 max = corr[i];
1526 lag = i;
1527 }
1528 }
1529
1530 /*-----------------------------------------------------------------------*
1531 * Find fractional pitch *
1532 *-----------------------------------------------------------------------*/
1533 if ((delta_search == 0) && (lag > max_frac_lag))
1534 {
1535
1536 /* full search and integer pitch greater than max_frac_lag */
1537 /* fractional search is not needed, set fractional to zero */
1538
1539 frac = 0;
1540 }
1541 else
1542 {
1543
1544 /* if differential search AND mode MR475 OR MR515 OR MR59 OR MR67 */
1545 /* then search fractional with 4 bits resolution */
1546
1547 if ((delta_search != 0) &&
1548 ((mode == MR475) || (mode == MR515) ||
1549 (mode == MR59) || (mode == MR67)))
1550 {
1551
1552 /* modify frac or last_frac according to position of last */
1553 /* integer pitch: either search around integer pitch, */
1554 /* or only on left or right side */
1555
1556 tmp_lag = st->T0_prev_subframe;
1557 if (sub(sub(tmp_lag, t0_min, pOverflow), 5, pOverflow) > 0)
1558 tmp_lag = add(t0_min, 5, pOverflow);
1559 if (sub(sub(t0_max, tmp_lag, pOverflow), 4, pOverflow) > 0)
1560 tmp_lag = sub(t0_max, 4, pOverflow);
1561
1562 if ((lag == tmp_lag) || (lag == (tmp_lag - 1)))
1563 {
1564
1565 /* normal search in fractions around T0 */
1566
1567 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
1568
1569 }
1570 else if (lag == (tmp_lag - 2))
1571 {
1572 /* limit search around T0 to the right side */
1573 frac = 0;
1574 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
1575 }
1576 else if (lag == (tmp_lag + 1))
1577 {
1578 /* limit search around T0 to the left side */
1579 last_frac = 0;
1580 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
1581 }
1582 else
1583 {
1584 /* no fractional search */
1585 frac = 0;
1586 }
1587 }
1588 else
1589 /* test the fractions around T0 */
1590 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
1591 }
1592
1593 /*-----------------------------------------------------------------------*
1594 * encode pitch *
1595 *-----------------------------------------------------------------------*/
1596
1597 if (flag3 != 0)
1598 {
1599 /* flag4 indicates encoding with 4 bit resolution; */
1600 /* this is needed for mode MR475, MR515 and MR59 */
1601
1602 flag4 = 0;
1603 if ((mode == MR475) || (mode == MR515) ||
1604 (mode == MR59) || (mode == MR67))
1605 {
1606 flag4 = 1;
1607 }
1608
1609 /* encode with 1/3 subsample resolution */
1610
1611 *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
1612 t0_min, t0_max, delta_search, flag4, pOverflow);
1613 /* function result */
1614
1615 }
1616 else
1617 {
1618 /* encode with 1/6 subsample resolution */
1619
1620 *ana_index = Enc_lag6(lag, frac, t0_min, delta_search, pOverflow);
1621 /* function result */
1622 }
1623
1624 /*-----------------------------------------------------------------------*
1625 * update state variables *
1626 *-----------------------------------------------------------------------*/
1627
1628 st->T0_prev_subframe = lag;
1629
1630 /*-----------------------------------------------------------------------*
1631 * update output variables *
1632 *-----------------------------------------------------------------------*/
1633
1634 *resu3 = flag3;
1635
1636 *pit_frac = frac;
1637
1638 return (lag);
1639 }
1640
1641