xref: /aosp_15_r20/frameworks/av/media/module/codecs/amrnb/enc/src/pitch_fr.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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