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