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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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 */
126static 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
206static 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
312static 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
493static 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
565static 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
677static 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*/
719static 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
795int 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*/
839Word16 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
907int 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*/
942Word16 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
1000void 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*/
1034void 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
1109Word16 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*/
1363Word16 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