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 s2;
330     Word16 excf[L_SUBFR];
331     Word16 scaling;
332     Word16 h_fac;
333     Word16 *s_excf;
334     Word16 scaled_excf[L_SUBFR];
335     Word16 *p_s_excf;
336     Word16 *p_excf;
337     Word16  temp;
338     Word16 *p_x;
339     Word16 *p_h;
340 
341     k = -t_min;
342 
343     /* compute the filtered excitation for the first delay t_min */
344 
345     Convolve(&exc[k], h, excf, L_subfr);
346 
347     /* scale "excf[]" to avoid overflow */
348     s = 0;
349     p_s_excf = scaled_excf;
350     p_excf   = excf;
351 
352     for (j = (L_subfr >> 1); j != 0; j--)
353     {
354         temp = *(p_excf++);
355         *(p_s_excf++) = temp >> 2;
356         s += (Word32) temp * temp;
357         temp = *(p_excf++);
358         *(p_s_excf++) = temp >> 2;
359         s += (Word32) temp * temp;
360     }
361 
362 
363     if (s <= (67108864L >> 1))
364     {
365         s_excf = excf;
366         h_fac = 12;
367         scaling = 0;
368     }
369     else
370     {
371         /* "excf[]" is divided by 2 */
372         s_excf = scaled_excf;
373         h_fac = 14;
374         scaling = 2;
375     }
376 
377     /* loop for every possible period */
378 
379     for (i = t_min; i <= t_max; i++)
380     {
381         /* Compute 1/sqrt(energy of excf[]) */
382 
383         s   = s2 = 0;
384         p_x      = xn;
385         p_s_excf = s_excf;
386         j        = L_subfr >> 1;
387 
388         while (j--)
389         {
390             s  += (Word32) * (p_x++) * *(p_s_excf);
391             s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf)));
392             p_s_excf++;
393             s  += (Word32) * (p_x++) * *(p_s_excf);
394             s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf)));
395             p_s_excf++;
396         }
397 
398         s2     = s2 << 1;
399         s2     = Inv_sqrt(s2, pOverflow);
400         norm_h = (Word16)(s2 >> 16);
401         norm_l = (Word16)((s2 >> 1) - (norm_h << 15));
402         corr_h = (Word16)(s >> 15);
403         corr_l = (Word16)((s) - (corr_h << 15));
404 
405         /* Normalize correlation = correlation * (1/sqrt(energy)) */
406 
407         s = Mpy_32(corr_h, corr_l, norm_h, norm_l, pOverflow);
408 
409         corr_norm[i] = (Word16) s ;
410 
411         /* modify the filtered excitation excf[] for the next iteration */
412         if (i != t_max)
413         {
414             k--;
415             temp = exc[k];
416             p_s_excf = &s_excf[L_subfr - 1];
417             p_h = &h[L_subfr - 1];
418 
419             p_excf = &s_excf[L_subfr - 2];
420             for (j = (L_subfr - 1) >> 1; j != 0; j--)
421             {
422                 s = ((Word32) temp * *(p_h--)) >> h_fac;
423                 *(p_s_excf--) = (Word16) s  + *(p_excf--);
424                 s = ((Word32) temp * *(p_h--)) >> h_fac;
425                 *(p_s_excf--) = (Word16) s  + *(p_excf--);
426             }
427 
428             s = ((Word32) temp * *(p_h)) >> h_fac;
429             *(p_s_excf--) = (Word16) s  + *(p_excf);
430 
431             *(p_s_excf) = temp >> scaling;
432         }
433 
434     }
435     return;
436 }
437 
438 /****************************************************************************/
439 
440 
441 /*
442 ------------------------------------------------------------------------------
443  FUNCTION NAME: searchFrac
444 ------------------------------------------------------------------------------
445  INPUT AND OUTPUT DEFINITIONS
446 
447  Inputs:
448     lag = pointer to integer pitch of type Word16
449     frac = pointer to starting point of search fractional pitch of type Word16
450     last_frac = endpoint of search  of type Word16
451     corr[] = pointer to normalized correlation of type Word16
452     flag3 = subsample resolution (3: =1 / 6: =0) of type Word16
453 
454  Outputs:
455     None
456 
457  Returns:
458     None
459 
460  Global Variables Used:
461     None
462 
463  Local Variables Needed:
464     None
465 
466 ------------------------------------------------------------------------------
467  FUNCTION DESCRIPTION
468 
469    FUNCTION:   searchFrac()
470 
471    PURPOSE: Find fractional pitch
472 
473    DESCRIPTION:
474       The function interpolates the normalized correlation at the
475       fractional positions around lag T0. The position at which the
476       interpolation function reaches its maximum is the fractional pitch.
477       Starting point of the search is frac, end point is last_frac.
478       frac is overwritten with the fractional pitch.
479 
480 ------------------------------------------------------------------------------
481  REQUIREMENTS
482 
483  None
484 
485 ------------------------------------------------------------------------------
486  REFERENCES
487 
488  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
489 
490 ------------------------------------------------------------------------------
491  PSEUDO-CODE
492 
493 static void searchFrac (
494     Word16 *lag,       // i/o : integer pitch
495     Word16 *frac,      // i/o : start point of search -
496                                fractional pitch
497     Word16 last_frac,  // i   : endpoint of search
498     Word16 corr[],     // i   : normalized correlation
499     Word16 flag3       // i   : subsample resolution
500                                 (3: =1 / 6: =0)
501 )
502 {
503     Word16 i;
504     Word16 max;
505     Word16 corr_int;
506 
507     // Test the fractions around T0 and choose the one which maximizes
508     // the interpolated normalized correlation.
509 
510     max = Interpol_3or6 (&corr[*lag], *frac, flag3); // function result
511 
512     for (i = add (*frac, 1); i <= last_frac; i++) {
513         corr_int = Interpol_3or6 (&corr[*lag], i, flag3);
514         if (sub (corr_int, max) > 0) {
515             max = corr_int;
516             *frac = i;
517         }
518     }
519 
520     if (flag3 == 0) {
521         // Limit the fraction value in the interval [-2,-1,0,1,2,3]
522 
523         if (sub (*frac, -3) == 0) {
524             *frac = 3;
525             *lag = sub (*lag, 1);
526         }
527     }
528     else {
529         // limit the fraction value between -1 and 1
530 
531         if (sub (*frac, -2) == 0) {
532             *frac = 1;
533             *lag = sub (*lag, 1);
534         }
535         if (sub (*frac, 2) == 0) {
536             *frac = -1;
537             *lag = add (*lag, 1);
538         }
539     }
540 }
541 
542 ------------------------------------------------------------------------------
543  RESOURCES USED [optional]
544 
545  When the code is written for a specific target processor the
546  the resources used should be documented below.
547 
548  HEAP MEMORY USED: x bytes
549 
550  STACK MEMORY USED: x bytes
551 
552  CLOCK CYCLES: (cycle count equation for this function) + (variable
553                 used to represent cycle count for each subroutine
554                 called)
555      where: (cycle count variable) = cycle count for [subroutine
556                                      name]
557 
558 ------------------------------------------------------------------------------
559  CAUTION [optional]
560  [State any special notes, constraints or cautions for users of this function]
561 
562 ------------------------------------------------------------------------------
563 */
564 
searchFrac(Word16 * lag,Word16 * frac,Word16 last_frac,Word16 corr[],Word16 flag3,Flag * pOverflow)565 static void searchFrac(
566     Word16 *lag,       /* i/o : integer pitch           */
567     Word16 *frac,      /* i/o : start point of search -
568                                 fractional pitch        */
569     Word16 last_frac,  /* i   : endpoint of search      */
570     Word16 corr[],     /* i   : normalized correlation  */
571     Word16 flag3,      /* i   : subsample resolution
572                                 (3: =1 / 6: =0)         */
573     Flag   *pOverflow
574 )
575 {
576     Word16 i;
577     Word16 max;
578     Word16 corr_int;
579 
580     /* Test the fractions around T0 and choose the one which maximizes   */
581     /* the interpolated normalized correlation.                          */
582 
583     max = Interpol_3or6(&corr[*lag], *frac, flag3, pOverflow);
584     /* function result */
585 
586     for (i = *frac + 1; i <= last_frac; i++)
587     {
588         corr_int = Interpol_3or6(&corr[*lag], i, flag3, pOverflow);
589         if (corr_int > max)
590         {
591             max = corr_int;
592             *frac = i;
593         }
594     }
595 
596     if (flag3 == 0)
597     {
598         /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */
599 
600         if (*frac == -3)
601         {
602             *frac = 3;
603             (*lag)--;
604         }
605     }
606     else
607     {
608         /* limit the fraction value between -1 and 1 */
609 
610         if (*frac == -2)
611         {
612             *frac = 1;
613             (*lag)--;
614         }
615         if (*frac == 2)
616         {
617             *frac = -1;
618             (*lag)++;
619         }
620     }
621 }
622 
623 /****************************************************************************/
624 
625 
626 /*
627 ------------------------------------------------------------------------------
628  FUNCTION NAME: getRange
629 ------------------------------------------------------------------------------
630  INPUT AND OUTPUT DEFINITIONS
631 
632  Inputs:
633     T0 = integer pitch of type Word16
634     delta_low = search start offset of type Word16
635     delta_range = search range of type Word16
636     pitmin = minimum pitch of type Word16
637     pitmax = maximum pitch of type Word16
638     t0_min = search range minimum of type Word16
639     t0_max = search range maximum of type Word16
640 
641  Outputs:
642     pOverflow = 1 if the math functions called result in overflow else zero.
643 
644  Returns:
645     None
646 
647  Global Variables Used:
648     None
649 
650  Local Variables Needed:
651     None
652 
653 ------------------------------------------------------------------------------
654  FUNCTION DESCRIPTION
655 
656    FUNCTION:   getRange()
657 
658    PURPOSE: Sets range around open-loop pitch or integer pitch of last subframe
659 
660    DESCRIPTION:
661       Takes integer pitch T0 and calculates a range around it with
662         t0_min = T0-delta_low  and t0_max = (T0-delta_low) + delta_range
663       t0_min and t0_max are bounded by pitmin and pitmax
664 ------------------------------------------------------------------------------
665  REQUIREMENTS
666 
667  None
668 
669 ------------------------------------------------------------------------------
670  REFERENCES
671 
672  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
673 
674 ------------------------------------------------------------------------------
675  PSEUDO-CODE
676 
677 static void getRange (
678     Word16 T0,           // i : integer pitch
679     Word16 delta_low,    // i : search start offset
680     Word16 delta_range,  // i : search range
681     Word16 pitmin,       // i : minimum pitch
682     Word16 pitmax,       // i : maximum pitch
683     Word16 *t0_min,      // o : search range minimum
684     Word16 *t0_max)      // o : search range maximum
685 {
686     *t0_min = sub(T0, delta_low);
687     if (sub(*t0_min, pitmin) < 0) {
688         *t0_min = pitmin;
689     }
690     *t0_max = add(*t0_min, delta_range);
691     if (sub(*t0_max, pitmax) > 0) {
692         *t0_max = pitmax;
693         *t0_min = sub(*t0_max, delta_range);
694     }
695 }
696 
697 ------------------------------------------------------------------------------
698  RESOURCES USED [optional]
699 
700  When the code is written for a specific target processor the
701  the resources used should be documented below.
702 
703  HEAP MEMORY USED: x bytes
704 
705  STACK MEMORY USED: x bytes
706 
707  CLOCK CYCLES: (cycle count equation for this function) + (variable
708                 used to represent cycle count for each subroutine
709                 called)
710      where: (cycle count variable) = cycle count for [subroutine
711                                      name]
712 
713 ------------------------------------------------------------------------------
714  CAUTION [optional]
715  [State any special notes, constraints or cautions for users of this function]
716 
717 ------------------------------------------------------------------------------
718 */
getRange(Word16 T0,Word16 delta_low,Word16 delta_range,Word16 pitmin,Word16 pitmax,Word16 * t0_min,Word16 * t0_max,Flag * pOverflow)719 static void getRange(
720     Word16 T0,           /* i : integer pitch          */
721     Word16 delta_low,    /* i : search start offset    */
722     Word16 delta_range,  /* i : search range           */
723     Word16 pitmin,       /* i : minimum pitch          */
724     Word16 pitmax,       /* i : maximum pitch          */
725     Word16 *t0_min,      /* o : search range minimum   */
726     Word16 *t0_max,      /* o : search range maximum   */
727     Flag   *pOverflow)
728 {
729 
730     Word16 temp;
731     OSCL_UNUSED_ARG(pOverflow);
732 
733     temp = *t0_min;
734     temp = T0 - delta_low;
735     if (temp < pitmin)
736     {
737         temp = pitmin;
738     }
739     *t0_min = temp;
740 
741     temp +=  delta_range;
742     if (temp > pitmax)
743     {
744         temp = pitmax;
745         *t0_min = pitmax - delta_range;
746     }
747     *t0_max = temp;
748 
749 }
750 
751 
752 /****************************************************************************/
753 
754 
755 /*
756 ------------------------------------------------------------------------------
757  FUNCTION NAME: Pitch_fr_init
758 ------------------------------------------------------------------------------
759  INPUT AND OUTPUT DEFINITIONS
760 
761  Inputs:
762     state = pointer to a pointer of structure type Pitch_fr_State.
763 
764  Outputs:
765     None
766 
767  Returns:
768     Returns a zero if successful and -1 if not successful.
769 
770  Global Variables Used:
771     None
772 
773  Local Variables Needed:
774     None
775 
776 ------------------------------------------------------------------------------
777  FUNCTION DESCRIPTION
778 
779   Function:   Pitch_fr_init
780   Purpose:    Allocates state memory and initializes state memory
781 
782 ------------------------------------------------------------------------------
783  REQUIREMENTS
784 
785  None
786 
787 ------------------------------------------------------------------------------
788  REFERENCES
789 
790  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
791 
792 ------------------------------------------------------------------------------
793  PSEUDO-CODE
794 
795 int Pitch_fr_init (Pitch_frState **state)
796 {
797     Pitch_frState* s;
798 
799     if (state == (Pitch_frState **) NULL){
800         // fprintf(stderr, "Pitch_fr_init: invalid parameter\n");
801         return -1;
802     }
803     *state = NULL;
804 
805     // allocate memory
806     if ((s= (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL){
807         // fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n");
808         return -1;
809     }
810 
811     Pitch_fr_reset(s);
812     *state = s;
813 
814     return 0;
815 }
816 
817 ------------------------------------------------------------------------------
818  RESOURCES USED [optional]
819 
820  When the code is written for a specific target processor the
821  the resources used should be documented below.
822 
823  HEAP MEMORY USED: x bytes
824 
825  STACK MEMORY USED: x bytes
826 
827  CLOCK CYCLES: (cycle count equation for this function) + (variable
828                 used to represent cycle count for each subroutine
829                 called)
830      where: (cycle count variable) = cycle count for [subroutine
831                                      name]
832 
833 ------------------------------------------------------------------------------
834  CAUTION [optional]
835  [State any special notes, constraints or cautions for users of this function]
836 
837 ------------------------------------------------------------------------------
838 */
Pitch_fr_init(Pitch_frState ** state)839 Word16 Pitch_fr_init(Pitch_frState **state)
840 {
841     Pitch_frState* s;
842 
843     if (state == (Pitch_frState **) NULL)
844     {
845         /* fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); */
846         return -1;
847     }
848     *state = NULL;
849 
850     /* allocate memory */
851     if ((s = (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL)
852     {
853         /* fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n"); */
854         return -1;
855     }
856 
857     Pitch_fr_reset(s);
858     *state = s;
859 
860     return 0;
861 }
862 
863 
864 /****************************************************************************/
865 
866 
867 /*
868 ------------------------------------------------------------------------------
869  FUNCTION NAME: Pitch_fr_reset
870 ------------------------------------------------------------------------------
871  INPUT AND OUTPUT DEFINITIONS
872 
873  Inputs:
874     state = pointer to a pointer of structure type Pitch_fr_State.
875 
876  Outputs:
877     None
878 
879  Returns:
880     Returns a zero if successful and -1 if not successful.
881 
882  Global Variables Used:
883     None
884 
885  Local Variables Needed:
886     None
887 
888 ------------------------------------------------------------------------------
889  FUNCTION DESCRIPTION
890 
891   Function:   Pitch_fr_reset
892   Purpose:    Initializes state memory to zero
893 
894 ------------------------------------------------------------------------------
895  REQUIREMENTS
896 
897  None
898 
899 ------------------------------------------------------------------------------
900  REFERENCES
901 
902  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
903 
904 ------------------------------------------------------------------------------
905  PSEUDO-CODE
906 
907 int Pitch_fr_reset (Pitch_frState *state)
908 {
909 
910     if (state == (Pitch_frState *) NULL){
911         // fprintf(stderr, "Pitch_fr_reset: invalid parameter\n");
912         return -1;
913     }
914 
915     state->T0_prev_subframe = 0;
916 
917     return 0;
918 }
919 
920 ------------------------------------------------------------------------------
921  RESOURCES USED [optional]
922 
923  When the code is written for a specific target processor the
924  the resources used should be documented below.
925 
926  HEAP MEMORY USED: x bytes
927 
928  STACK MEMORY USED: x bytes
929 
930  CLOCK CYCLES: (cycle count equation for this function) + (variable
931                 used to represent cycle count for each subroutine
932                 called)
933      where: (cycle count variable) = cycle count for [subroutine
934                                      name]
935 
936 ------------------------------------------------------------------------------
937  CAUTION [optional]
938  [State any special notes, constraints or cautions for users of this function]
939 
940 ------------------------------------------------------------------------------
941 */
Pitch_fr_reset(Pitch_frState * state)942 Word16 Pitch_fr_reset(Pitch_frState *state)
943 {
944 
945     if (state == (Pitch_frState *) NULL)
946     {
947         /* fprintf(stderr, "Pitch_fr_reset: invalid parameter\n"); */
948         return -1;
949     }
950 
951     state->T0_prev_subframe = 0;
952 
953     return 0;
954 }
955 
956 
957 /****************************************************************************/
958 
959 
960 /*
961 ------------------------------------------------------------------------------
962  FUNCTION NAME: Pitch_fr_exit
963 ------------------------------------------------------------------------------
964  INPUT AND OUTPUT DEFINITIONS
965 
966  Inputs:
967     state = pointer to a pointer of structure type Pitch_fr_State.
968 
969  Outputs:
970     None
971 
972  Returns:
973     None
974 
975  Global Variables Used:
976     None
977 
978  Local Variables Needed:
979     None
980 
981 ------------------------------------------------------------------------------
982  FUNCTION DESCRIPTION
983 
984   Function:   Pitch_fr_exit
985   Purpose:    The memory for state is freed.
986 
987 ------------------------------------------------------------------------------
988  REQUIREMENTS
989 
990  None
991 
992 ------------------------------------------------------------------------------
993  REFERENCES
994 
995  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
996 
997 ------------------------------------------------------------------------------
998  PSEUDO-CODE
999 
1000 void Pitch_fr_exit (Pitch_frState **state)
1001 {
1002     if (state == NULL || *state == NULL)
1003         return;
1004 
1005     // deallocate memory
1006     free(*state);
1007     *state = NULL;
1008 
1009     return;
1010 }
1011 
1012 ------------------------------------------------------------------------------
1013  RESOURCES USED [optional]
1014 
1015  When the code is written for a specific target processor the
1016  the resources used should be documented below.
1017 
1018  HEAP MEMORY USED: x bytes
1019 
1020  STACK MEMORY USED: x bytes
1021 
1022  CLOCK CYCLES: (cycle count equation for this function) + (variable
1023                 used to represent cycle count for each subroutine
1024                 called)
1025      where: (cycle count variable) = cycle count for [subroutine
1026                                      name]
1027 
1028 ------------------------------------------------------------------------------
1029  CAUTION [optional]
1030  [State any special notes, constraints or cautions for users of this function]
1031 
1032 ------------------------------------------------------------------------------
1033 */
Pitch_fr_exit(Pitch_frState ** state)1034 void Pitch_fr_exit(Pitch_frState **state)
1035 {
1036     if (state == NULL || *state == NULL)
1037         return;
1038 
1039     /* deallocate memory */
1040     free(*state);
1041     *state = NULL;
1042 
1043     return;
1044 }
1045 
1046 /****************************************************************************/
1047 
1048 
1049 /*
1050 ------------------------------------------------------------------------------
1051  FUNCTION NAME: Pitch_fr
1052 ------------------------------------------------------------------------------
1053  INPUT AND OUTPUT DEFINITIONS
1054 
1055  Inputs:
1056     st = pointer to stat structure of type Pitch_frState
1057     mode = codec mode of type enum Mode
1058     T_op[] = pointer to open loop pitch lags of type Word16
1059     exc[] = pointer to excitation buffer of type Word16
1060     xn[] = pointer to target vector of type Word16
1061     h[] = pointer to impulse response of synthesis and weighting filters
1062           of type Word16
1063     L_subfr = length of subframe of type Word16
1064     i_subfr = subframe offset of type Word16
1065 
1066  Outputs:
1067     pit_frac = pointer to pitch period (fractional) of type Word16
1068     resu3 = pointer to subsample resolution of type Word16
1069     ana_index = pointer to index of encoding of type Word16
1070 
1071  Returns:
1072     None
1073 
1074  Global Variables Used:
1075     None
1076 
1077  Local Variables Needed:
1078     None
1079 
1080 ------------------------------------------------------------------------------
1081  FUNCTION DESCRIPTION
1082 
1083    FUNCTION:   Pitch_fr()
1084 
1085    PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution
1086             (closed loop).
1087 
1088    DESCRIPTION:
1089          - find the normalized correlation between the target and filtered
1090            past excitation in the search range.
1091          - select the delay with maximum normalized correlation.
1092          - interpolate the normalized correlation at fractions -3/6 to 3/6
1093            with step 1/6 around the chosen delay.
1094          - The fraction which gives the maximum interpolated value is chosen.
1095 
1096 ------------------------------------------------------------------------------
1097  REQUIREMENTS
1098 
1099  None
1100 
1101 ------------------------------------------------------------------------------
1102  REFERENCES
1103 
1104  pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1105 
1106 ------------------------------------------------------------------------------
1107  PSEUDO-CODE
1108 
1109 Word16 Pitch_fr (        // o   : pitch period (integer)
1110     Pitch_frState *st,   // i/o : State struct
1111     enum Mode mode,      // i   : codec mode
1112     Word16 T_op[],       // i   : open loop pitch lags
1113     Word16 exc[],        // i   : excitation buffer                      Q0
1114     Word16 xn[],         // i   : target vector                          Q0
1115     Word16 h[],          // i   : impulse response of synthesis and
1116                                   weighting filters                     Q12
1117     Word16 L_subfr,      // i   : Length of subframe
1118     Word16 i_subfr,      // i   : subframe offset
1119     Word16 *pit_frac,    // o   : pitch period (fractional)
1120     Word16 *resu3,       // o   : subsample resolution 1/3 (=1) or 1/6 (=0)
1121     Word16 *ana_index    // o   : index of encoding
1122 )
1123 {
1124     Word16 i;
1125     Word16 t_min, t_max;
1126     Word16 t0_min, t0_max;
1127     Word16 max, lag, frac;
1128     Word16 tmp_lag;
1129     Word16 *corr;
1130     Word16 corr_v[40];    // Total length = t0_max-t0_min+1+2*L_INTER_SRCH
1131 
1132     Word16 max_frac_lag;
1133     Word16 flag3, flag4;
1134     Word16 last_frac;
1135     Word16 delta_int_low, delta_int_range;
1136     Word16 delta_frc_low, delta_frc_range;
1137     Word16 pit_min;
1138     Word16 frame_offset;
1139     Word16 delta_search;
1140 
1141     //-----------------------------------------------------------------------
1142      //                      set mode specific variables
1143      //----------------------------------------------------------------------
1144 
1145     max_frac_lag    = mode_dep_parm[mode].max_frac_lag;
1146     flag3           = mode_dep_parm[mode].flag3;
1147     frac            = mode_dep_parm[mode].first_frac;
1148     last_frac       = mode_dep_parm[mode].last_frac;
1149     delta_int_low   = mode_dep_parm[mode].delta_int_low;
1150     delta_int_range = mode_dep_parm[mode].delta_int_range;
1151 
1152     delta_frc_low   = mode_dep_parm[mode].delta_frc_low;
1153     delta_frc_range = mode_dep_parm[mode].delta_frc_range;
1154     pit_min         = mode_dep_parm[mode].pit_min;
1155 
1156     //-----------------------------------------------------------------------
1157     //                 decide upon full or differential search
1158     //-----------------------------------------------------------------------
1159 
1160     delta_search = 1;
1161 
1162     if ((i_subfr == 0) || (sub(i_subfr,L_FRAME_BY2) == 0)) {
1163 
1164         // Subframe 1 and 3
1165 
1166         if (((sub((Word16)mode, (Word16)MR475) != 0) && (sub((Word16)mode,
1167             (Word16)MR515) != 0)) ||
1168             (sub(i_subfr,L_FRAME_BY2) != 0)) {
1169 
1170             // set t0_min, t0_max for full search
1171             // this is *not* done for mode MR475, MR515 in subframe 3
1172 
1173             delta_search = 0; // no differential search
1174 
1175             // calculate index into T_op which contains the open-loop
1176             // pitch estimations for the 2 big subframes
1177 
1178             frame_offset = 1;
1179             if (i_subfr == 0)
1180                 frame_offset = 0;
1181 
1182             // get T_op from the corresponding half frame and
1183             // set t0_min, t0_max
1184 
1185             getRange (T_op[frame_offset], delta_int_low, delta_int_range,
1186                       pit_min, PIT_MAX, &t0_min, &t0_max);
1187         }
1188         else {
1189 
1190             // mode MR475, MR515 and 3. Subframe: delta search as well
1191             getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1192                       pit_min, PIT_MAX, &t0_min, &t0_max);
1193         }
1194     }
1195     else {
1196 
1197         // for Subframe 2 and 4
1198         // get range around T0 of previous subframe for delta search
1199 
1200         getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1201                   pit_min, PIT_MAX, &t0_min, &t0_max);
1202     }
1203 
1204     //-----------------------------------------------------------------------
1205                 Find interval to compute normalized correlation
1206      -----------------------------------------------------------------------
1207 
1208     t_min = sub (t0_min, L_INTER_SRCH);
1209     t_max = add (t0_max, L_INTER_SRCH);
1210 
1211     corr = &corr_v[-t_min];
1212 
1213     //-----------------------------------------------------------------------
1214       Compute normalized correlation between target and filtered excitation
1215      -----------------------------------------------------------------------
1216 
1217     Norm_Corr (exc, xn, h, L_subfr, t_min, t_max, corr);
1218 
1219     //-----------------------------------------------------------------------
1220                                 Find integer pitch
1221      -----------------------------------------------------------------------
1222 
1223     max = corr[t0_min];
1224     lag = t0_min;
1225 
1226     for (i = t0_min + 1; i <= t0_max; i++) {
1227         if (sub (corr[i], max) >= 0) {
1228             max = corr[i];
1229             lag = i;
1230         }
1231     }
1232 
1233     //-----------------------------------------------------------------------
1234                              Find fractional pitch
1235      -----------------------------------------------------------------------
1236     if ((delta_search == 0) && (sub (lag, max_frac_lag) > 0)) {
1237 
1238         // full search and integer pitch greater than max_frac_lag
1239         // fractional search is not needed, set fractional to zero
1240 
1241         frac = 0;
1242     }
1243     else {
1244 
1245         // if differential search AND mode MR475 OR MR515 OR MR59 OR MR67
1246         // then search fractional with 4 bits resolution
1247 
1248        if ((delta_search != 0) &&
1249            ((sub ((Word16)mode, (Word16)MR475) == 0) ||
1250             (sub ((Word16)mode, (Word16)MR515) == 0) ||
1251             (sub ((Word16)mode, (Word16)MR59) == 0) ||
1252             (sub ((Word16)mode, (Word16)MR67) == 0))) {
1253 
1254           // modify frac or last_frac according to position of last
1255           // integer pitch: either search around integer pitch,
1256           // or only on left or right side
1257 
1258           tmp_lag = st->T0_prev_subframe;
1259           if ( sub( sub(tmp_lag, t0_min), 5) > 0)
1260              tmp_lag = add (t0_min, 5);
1261           if ( sub( sub(t0_max, tmp_lag), 4) > 0)
1262                tmp_lag = sub (t0_max, 4);
1263 
1264           if ((sub (lag, tmp_lag) == 0) ||
1265               (sub (lag, sub(tmp_lag, 1)) == 0)) {
1266 
1267              // normal search in fractions around T0
1268 
1269              searchFrac (&lag, &frac, last_frac, corr, flag3);
1270 
1271           }
1272           else if (sub (lag, sub (tmp_lag, 2)) == 0) {
1273              // limit search around T0 to the right side
1274              frac = 0;
1275              searchFrac (&lag, &frac, last_frac, corr, flag3);
1276           }
1277           else if (sub (lag, add(tmp_lag, 1)) == 0) {
1278              // limit search around T0 to the left side
1279              last_frac = 0;
1280              searchFrac (&lag, &frac, last_frac, corr, flag3);
1281           }
1282           else {
1283              // no fractional search
1284              frac = 0;
1285             }
1286        }
1287        else
1288           // test the fractions around T0
1289           searchFrac (&lag, &frac, last_frac, corr, flag3);
1290     }
1291 
1292     //-----------------------------------------------------------------------
1293      //                           encode pitch
1294      //-----------------------------------------------------------------------
1295 
1296     if (flag3 != 0) {
1297        // flag4 indicates encoding with 4 bit resolution;
1298        // this is needed for mode MR475, MR515 and MR59
1299 
1300        flag4 = 0;
1301        if ( (sub ((Word16)mode, (Word16)MR475) == 0) ||
1302             (sub ((Word16)mode, (Word16)MR515) == 0) ||
1303             (sub ((Word16)mode, (Word16)MR59) == 0) ||
1304             (sub ((Word16)mode, (Word16)MR67) == 0) ) {
1305           flag4 = 1;
1306        }
1307 
1308        // encode with 1/3 subsample resolution
1309 
1310        *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
1311                              t0_min, t0_max, delta_search, flag4);
1312        // function result
1313 
1314     }
1315     else
1316     {
1317        // encode with 1/6 subsample resolution
1318 
1319        *ana_index = Enc_lag6(lag, frac, t0_min, delta_search);
1320        // function result
1321     }
1322 
1323      //-----------------------------------------------------------------------
1324      //                          update state variables
1325      //-----------------------------------------------------------------------
1326 
1327     st->T0_prev_subframe = lag;
1328 
1329      //-----------------------------------------------------------------------
1330      //                      update output variables
1331      //-----------------------------------------------------------------------
1332 
1333     *resu3    = flag3;
1334 
1335     *pit_frac = frac;
1336 
1337     return (lag);
1338 }
1339 
1340 
1341 ------------------------------------------------------------------------------
1342  RESOURCES USED [optional]
1343 
1344  When the code is written for a specific target processor the
1345  the resources used should be documented below.
1346 
1347  HEAP MEMORY USED: x bytes
1348 
1349  STACK MEMORY USED: x bytes
1350 
1351  CLOCK CYCLES: (cycle count equation for this function) + (variable
1352                 used to represent cycle count for each subroutine
1353                 called)
1354      where: (cycle count variable) = cycle count for [subroutine
1355                                      name]
1356 
1357 ------------------------------------------------------------------------------
1358  CAUTION [optional]
1359  [State any special notes, constraints or cautions for users of this function]
1360 
1361 ------------------------------------------------------------------------------
1362 */
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)1363 Word16 Pitch_fr(         /* o   : pitch period (integer)                    */
1364     Pitch_frState *st,   /* i/o : State struct                              */
1365     enum Mode mode,      /* i   : codec mode                                */
1366     Word16 T_op[],       /* i   : open loop pitch lags                      */
1367     Word16 exc[],        /* i   : excitation buffer                      Q0 */
1368     Word16 xn[],         /* i   : target vector                          Q0 */
1369     Word16 h[],          /* i   : impulse response of synthesis and
1370                                   weighting filters                     Q12 */
1371     Word16 L_subfr,      /* i   : Length of subframe                        */
1372     Word16 i_subfr,      /* i   : subframe offset                           */
1373     Word16 *pit_frac,    /* o   : pitch period (fractional)                 */
1374     Word16 *resu3,       /* o   : subsample resolution 1/3 (=1) or 1/6 (=0) */
1375     Word16 *ana_index,   /* o   : index of encoding                         */
1376     Flag   *pOverflow
1377 )
1378 {
1379     Word16 i;
1380     Word16 t_min;
1381     Word16 t_max;
1382     Word16 t0_min = 0;
1383     Word16 t0_max;
1384     Word16 max;
1385     Word16 lag;
1386     Word16 frac;
1387     Word16 tmp_lag;
1388     Word16 *corr;
1389     Word16 corr_v[40];    /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */
1390 
1391     Word16 max_frac_lag;
1392     Word16 flag3;
1393     Word16 flag4;
1394     Word16 last_frac;
1395     Word16 delta_int_low;
1396     Word16 delta_int_range;
1397     Word16 delta_frc_low;
1398     Word16 delta_frc_range;
1399     Word16 pit_min;
1400     Word16 frame_offset;
1401     Word16 delta_search;
1402 
1403     /*-----------------------------------------------------------------------*
1404      *                      set mode specific variables                      *
1405      *-----------------------------------------------------------------------*/
1406 
1407     max_frac_lag    = mode_dep_parm[mode].max_frac_lag;
1408     flag3           = mode_dep_parm[mode].flag3;
1409     frac            = mode_dep_parm[mode].first_frac;
1410     last_frac       = mode_dep_parm[mode].last_frac;
1411     delta_int_low   = mode_dep_parm[mode].delta_int_low;
1412     delta_int_range = mode_dep_parm[mode].delta_int_range;
1413 
1414     delta_frc_low   = mode_dep_parm[mode].delta_frc_low;
1415     delta_frc_range = mode_dep_parm[mode].delta_frc_range;
1416     pit_min         = mode_dep_parm[mode].pit_min;
1417 
1418     /*-----------------------------------------------------------------------*
1419      *                 decide upon full or differential search               *
1420      *-----------------------------------------------------------------------*/
1421 
1422     delta_search = 1;
1423 
1424     if ((i_subfr == 0) || (i_subfr == L_FRAME_BY2))
1425     {
1426 
1427         /* Subframe 1 and 3 */
1428 
1429         if (((mode != MR475) && (mode != MR515)) || (i_subfr != L_FRAME_BY2))
1430         {
1431 
1432             /* set t0_min, t0_max for full search */
1433             /* this is *not* done for mode MR475, MR515 in subframe 3 */
1434 
1435             delta_search = 0; /* no differential search */
1436 
1437             /* calculate index into T_op which contains the open-loop */
1438             /* pitch estimations for the 2 big subframes */
1439 
1440             frame_offset = 1;
1441             if (i_subfr == 0)
1442                 frame_offset = 0;
1443 
1444             /* get T_op from the corresponding half frame and */
1445             /* set t0_min, t0_max */
1446 
1447             getRange(T_op[frame_offset], delta_int_low, delta_int_range,
1448                      pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1449         }
1450         else
1451         {
1452 
1453             /* mode MR475, MR515 and 3. Subframe: delta search as well */
1454             getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1455                      pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1456         }
1457     }
1458     else
1459     {
1460 
1461         /* for Subframe 2 and 4 */
1462         /* get range around T0 of previous subframe for delta search */
1463 
1464         getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range,
1465                  pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow);
1466     }
1467 
1468     /*-----------------------------------------------------------------------*
1469      *           Find interval to compute normalized correlation             *
1470      *-----------------------------------------------------------------------*/
1471 
1472     t_min = sub(t0_min, L_INTER_SRCH, pOverflow);
1473     t_max = add(t0_max, L_INTER_SRCH, pOverflow);
1474 
1475     corr = &corr_v[-t_min];
1476 
1477     /*-----------------------------------------------------------------------*
1478      * Compute normalized correlation between target and filtered excitation *
1479      *-----------------------------------------------------------------------*/
1480 
1481     Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr, pOverflow);
1482 
1483     /*-----------------------------------------------------------------------*
1484      *                           Find integer pitch                          *
1485      *-----------------------------------------------------------------------*/
1486 
1487     max = corr[t0_min];
1488     lag = t0_min;
1489 
1490     for (i = t0_min + 1; i <= t0_max; i++)
1491     {
1492         if (corr[i] >= max)
1493         {
1494             max = corr[i];
1495             lag = i;
1496         }
1497     }
1498 
1499     /*-----------------------------------------------------------------------*
1500      *                        Find fractional pitch                          *
1501      *-----------------------------------------------------------------------*/
1502     if ((delta_search == 0) && (lag > max_frac_lag))
1503     {
1504 
1505         /* full search and integer pitch greater than max_frac_lag */
1506         /* fractional search is not needed, set fractional to zero */
1507 
1508         frac = 0;
1509     }
1510     else
1511     {
1512 
1513         /* if differential search AND mode MR475 OR MR515 OR MR59 OR MR67   */
1514         /* then search fractional with 4 bits resolution           */
1515 
1516         if ((delta_search != 0) &&
1517                 ((mode == MR475) || (mode == MR515) ||
1518                  (mode == MR59) || (mode == MR67)))
1519         {
1520 
1521             /* modify frac or last_frac according to position of last */
1522             /* integer pitch: either search around integer pitch, */
1523             /* or only on left or right side */
1524 
1525             tmp_lag = st->T0_prev_subframe;
1526             if (sub(sub(tmp_lag, t0_min, pOverflow), 5, pOverflow) > 0)
1527                 tmp_lag = add(t0_min, 5, pOverflow);
1528             if (sub(sub(t0_max, tmp_lag, pOverflow), 4, pOverflow) > 0)
1529                 tmp_lag = sub(t0_max, 4, pOverflow);
1530 
1531             if ((lag == tmp_lag) || (lag == (tmp_lag - 1)))
1532             {
1533 
1534                 /* normal search in fractions around T0 */
1535 
1536                 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
1537 
1538             }
1539             else if (lag == (tmp_lag - 2))
1540             {
1541                 /* limit search around T0 to the right side */
1542                 frac = 0;
1543                 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
1544             }
1545             else if (lag == (tmp_lag + 1))
1546             {
1547                 /* limit search around T0 to the left side */
1548                 last_frac = 0;
1549                 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
1550             }
1551             else
1552             {
1553                 /* no fractional search */
1554                 frac = 0;
1555             }
1556         }
1557         else
1558             /* test the fractions around T0 */
1559             searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
1560     }
1561 
1562     /*-----------------------------------------------------------------------*
1563      *                           encode pitch                                *
1564      *-----------------------------------------------------------------------*/
1565 
1566     if (flag3 != 0)
1567     {
1568         /* flag4 indicates encoding with 4 bit resolution;         */
1569         /* this is needed for mode MR475, MR515 and MR59           */
1570 
1571         flag4 = 0;
1572         if ((mode == MR475) || (mode == MR515) ||
1573                 (mode == MR59) || (mode == MR67))
1574         {
1575             flag4 = 1;
1576         }
1577 
1578         /* encode with 1/3 subsample resolution */
1579 
1580         *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe,
1581                               t0_min, t0_max, delta_search, flag4, pOverflow);
1582         /* function result */
1583 
1584     }
1585     else
1586     {
1587         /* encode with 1/6 subsample resolution */
1588 
1589         *ana_index = Enc_lag6(lag, frac, t0_min, delta_search, pOverflow);
1590         /* function result */
1591     }
1592 
1593     /*-----------------------------------------------------------------------*
1594      *                          update state variables                       *
1595      *-----------------------------------------------------------------------*/
1596 
1597     st->T0_prev_subframe = lag;
1598 
1599     /*-----------------------------------------------------------------------*
1600      *                      update output variables                          *
1601      *-----------------------------------------------------------------------*/
1602 
1603     *resu3    = flag3;
1604 
1605     *pit_frac = frac;
1606 
1607     return (lag);
1608 }
1609 
1610