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