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/p_ol_wgh.c
     35  Funtions: p_ol_wgh_init
     36            p_ol_wgh_reset
     37            p_ol_wgh_exit
     38            Lag_max
     39            Pitch_ol_wgh
     40 
     41      Date: 02/05/2002
     42 ------------------------------------------------------------------------------
     43  REVISION HISTORY
     44 
     45  Description: t0 was not being declared as Word32.
     46 
     47  Description:  Replaced OSCL mem type functions and eliminated include
     48                files that now are chosen by OSCL definitions
     49 
     50  Description:  Replaced "int" and/or "char" with OSCL defined types.
     51 
     52  Description: Changed round function name to pv_round to avoid conflict with
     53               round function in C standard library.
     54 
     55  Description:
     56 
     57 ------------------------------------------------------------------------------
     58  MODULE DESCRIPTION
     59 
     60  The modules in this file compute the open loop pitch lag with weighting.
     61 ------------------------------------------------------------------------------
     62 */
     63 
     64 
     65 /*----------------------------------------------------------------------------
     66 ; INCLUDES
     67 ----------------------------------------------------------------------------*/
     68 #include <stdlib.h>
     69 
     70 #include "p_ol_wgh.h"
     71 #include "typedef.h"
     72 #include "cnst.h"
     73 #include "basic_op.h"
     74 #include "gmed_n.h"
     75 #include "inv_sqrt.h"
     76 #include "vad1.h"
     77 #include "calc_cor.h"
     78 #include "hp_max.h"
     79 
     80 /*----------------------------------------------------------------------------
     81 ; MACROS
     82 ; Define module specific macros here
     83 ----------------------------------------------------------------------------*/
     84 
     85 
     86 /*----------------------------------------------------------------------------
     87 ; DEFINES
     88 ; Include all pre-processor statements here. Include conditional
     89 ; compile variables also.
     90 ----------------------------------------------------------------------------*/
     91 
     92 /*----------------------------------------------------------------------------
     93 ; LOCAL FUNCTION DEFINITIONS
     94 ; Function Prototype declaration
     95 ----------------------------------------------------------------------------*/
     96 
     97 /*----------------------------------------------------------------------------
     98 ; LOCAL VARIABLE DEFINITIONS
     99 ; Variable declaration - defined here and used outside this module
    100 ----------------------------------------------------------------------------*/
    101 
    102 
    103 /*
    104 ------------------------------------------------------------------------------
    105  FUNCTION NAME: p_ol_wgh_init
    106 ------------------------------------------------------------------------------
    107  INPUT AND OUTPUT DEFINITIONS
    108 
    109  Inputs
    110     state = pointer to a pointer of structure type pitchOLWghtState
    111 
    112  Outputs:
    113     None
    114 
    115  Returns:
    116     0 if the memory allocation is a success
    117     -1 if the memory allocation fails
    118 
    119  Global Variables Used:
    120     None.
    121 
    122  Local Variables Needed:
    123     None.
    124 
    125 ------------------------------------------------------------------------------
    126  FUNCTION DESCRIPTION
    127 
    128  This function allocates state memory and initializes state memory
    129 
    130 ------------------------------------------------------------------------------
    131  REQUIREMENTS
    132 
    133  None.
    134 
    135 ------------------------------------------------------------------------------
    136  REFERENCES
    137 
    138  p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    139 
    140 ------------------------------------------------------------------------------
    141  PSEUDO-CODE
    142 
    143 int p_ol_wgh_init (pitchOLWghtState **state)
    144 {
    145     pitchOLWghtState* s;
    146 
    147     if (state == (pitchOLWghtState **) NULL){
    148         // fprintf(stderr, "p_ol_wgh_init: invalid parameter\n");
    149         return -1;
    150     }
    151     *state = NULL;
    152 
    153     // allocate memory
    154     if ((s= (pitchOLWghtState *) malloc(sizeof(pitchOLWghtState))) == NULL){
    155         // fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n");
    156         return -1;
    157     }
    158 
    159     p_ol_wgh_reset(s);
    160 
    161     *state = s;
    162 
    163     return 0;
    164 }
    165 
    166 ------------------------------------------------------------------------------
    167  RESOURCES USED [optional]
    168 
    169  When the code is written for a specific target processor the
    170  the resources used should be documented below.
    171 
    172  HEAP MEMORY USED: x bytes
    173 
    174  STACK MEMORY USED: x bytes
    175 
    176  CLOCK CYCLES: (cycle count equation for this function) + (variable
    177                 used to represent cycle count for each subroutine
    178                 called)
    179      where: (cycle count variable) = cycle count for [subroutine
    180                                      name]
    181 
    182 ------------------------------------------------------------------------------
    183  CAUTION [optional]
    184  [State any special notes, constraints or cautions for users of this function]
    185 
    186 ------------------------------------------------------------------------------
    187 */
    188 
    189 Word16 p_ol_wgh_init(pitchOLWghtState **state)
    190 {
    191     pitchOLWghtState* s;
    192 
    193     if (state == (pitchOLWghtState **) NULL)
    194     {
    195         /* fprintf(stderr, "p_ol_wgh_init: invalid parameter\n"); */
    196         return -1;
    197     }
    198     *state = NULL;
    199 
    200     /* allocate memory */
    201     if ((s = (pitchOLWghtState *) malloc(sizeof(pitchOLWghtState))) == NULL)
    202     {
    203         /* fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n"); */
    204         return -1;
    205     }
    206 
    207     p_ol_wgh_reset(s);
    208 
    209     *state = s;
    210 
    211     return 0;
    212 }
    213 
    214 /*----------------------------------------------------------------------------
    215 ; End Function: p_ol_wgh_init
    216 ----------------------------------------------------------------------------*/
    217 
    218 /*
    219 ------------------------------------------------------------------------------
    220  FUNCTION NAME: p_ol_wgh_reset
    221 ------------------------------------------------------------------------------
    222  INPUT AND OUTPUT DEFINITIONS
    223 
    224  Inputs
    225     st = pointer to structure type pitchOLWghtState
    226 
    227  Outputs:
    228     None
    229 
    230  Returns:
    231     0 if the memory initialization is a success
    232     -1 if the memory initialization fails
    233 
    234  Global Variables Used:
    235     None.
    236 
    237  Local Variables Needed:
    238     None.
    239 
    240 ------------------------------------------------------------------------------
    241  FUNCTION DESCRIPTION
    242 
    243  This function initializes state memory to zero
    244 
    245 ------------------------------------------------------------------------------
    246  REQUIREMENTS
    247 
    248  None.
    249 
    250 ------------------------------------------------------------------------------
    251  REFERENCES
    252 
    253  p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    254 
    255 ------------------------------------------------------------------------------
    256  PSEUDO-CODE
    257 
    258 int p_ol_wgh_reset (pitchOLWghtState *st)
    259 {
    260    if (st == (pitchOLWghtState *) NULL){
    261       // fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n");
    262       return -1;
    263    }
    264 
    265    // Reset pitch search states
    266    st->old_T0_med = 40;
    267    st->ada_w = 0;
    268    st->wght_flg = 0;
    269 
    270    return 0;
    271 }
    272 
    273 ------------------------------------------------------------------------------
    274  RESOURCES USED [optional]
    275 
    276  When the code is written for a specific target processor the
    277  the resources used should be documented below.
    278 
    279  HEAP MEMORY USED: x bytes
    280 
    281  STACK MEMORY USED: x bytes
    282 
    283  CLOCK CYCLES: (cycle count equation for this function) + (variable
    284                 used to represent cycle count for each subroutine
    285                 called)
    286      where: (cycle count variable) = cycle count for [subroutine
    287                                      name]
    288 
    289 ------------------------------------------------------------------------------
    290  CAUTION [optional]
    291  [State any special notes, constraints or cautions for users of this function]
    292 
    293 ------------------------------------------------------------------------------
    294 */
    295 
    296 Word16 p_ol_wgh_reset(pitchOLWghtState *st)
    297 {
    298     if (st == (pitchOLWghtState *) NULL)
    299     {
    300         /* fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n"); */
    301         return -1;
    302     }
    303 
    304     /* Reset pitch search states */
    305     st->old_T0_med = 40;
    306     st->ada_w = 0;
    307     st->wght_flg = 0;
    308 
    309     return 0;
    310 }
    311 
    312 /*----------------------------------------------------------------------------
    313 ; End Function: p_ol_wgh_reset
    314 ----------------------------------------------------------------------------*/
    315 
    316 /*
    317 ------------------------------------------------------------------------------
    318  FUNCTION NAME: p_ol_wgh_exit
    319 ------------------------------------------------------------------------------
    320  INPUT AND OUTPUT DEFINITIONS
    321 
    322  Inputs
    323     st = pointer to a pointer of structure type pitchOLWghtState
    324 
    325  Outputs:
    326     None
    327 
    328  Returns:
    329     0 if the memory initialization is a success
    330     -1 if the memory initialization fails
    331 
    332  Global Variables Used:
    333     None.
    334 
    335  Local Variables Needed:
    336     None.
    337 
    338 ------------------------------------------------------------------------------
    339  FUNCTION DESCRIPTION
    340 
    341  This function frees the memory used for state memory
    342 
    343 ------------------------------------------------------------------------------
    344  REQUIREMENTS
    345 
    346  None.
    347 
    348 ------------------------------------------------------------------------------
    349  REFERENCES
    350 
    351  p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    352 
    353 ------------------------------------------------------------------------------
    354  PSEUDO-CODE
    355 
    356 void p_ol_wgh_exit (pitchOLWghtState **state)
    357 {
    358     if (state == NULL || *state == NULL)
    359         return;
    360 
    361     // deallocate memory
    362     free(*state);
    363     *state = NULL;
    364 
    365     return;
    366 }
    367 
    368 ------------------------------------------------------------------------------
    369  RESOURCES USED [optional]
    370 
    371  When the code is written for a specific target processor the
    372  the resources used should be documented below.
    373 
    374  HEAP MEMORY USED: x bytes
    375 
    376  STACK MEMORY USED: x bytes
    377 
    378  CLOCK CYCLES: (cycle count equation for this function) + (variable
    379                 used to represent cycle count for each subroutine
    380                 called)
    381      where: (cycle count variable) = cycle count for [subroutine
    382                                      name]
    383 
    384 ------------------------------------------------------------------------------
    385  CAUTION [optional]
    386  [State any special notes, constraints or cautions for users of this function]
    387 
    388 ------------------------------------------------------------------------------
    389 */
    390 
    391 void p_ol_wgh_exit(pitchOLWghtState **state)
    392 {
    393     if (state == NULL || *state == NULL)
    394         return;
    395 
    396     /* deallocate memory */
    397     free(*state);
    398     *state = NULL;
    399 
    400     return;
    401 }
    402 
    403 
    404 /*----------------------------------------------------------------------------
    405 ; End Function: p_ol_wgh_exit
    406 ----------------------------------------------------------------------------*/
    407 /*
    408 ------------------------------------------------------------------------------
    409  FUNCTION NAME: Lag_max
    410 ------------------------------------------------------------------------------
    411  INPUT AND OUTPUT DEFINITIONS
    412 
    413  Inputs:
    414     corr = pointer to buffer of correlation values (Word32)
    415     scal_sig = pointer to buffer of scaled signal values (Word16)
    416     scal_fac = scaled signal factor (Word16)
    417     scal_flag = EFR compatible scaling flag (Word16)
    418     L_frame = length of frame to compute pitch (Word16)
    419     lag_max = maximum lag (Word16)
    420     lag_min = minimum lag (Word16)
    421     cor_max = pointer to the normalized correlation of selected lag (Word16)
    422     rmax = pointer to max(<s[i]*s[j]>), (Word32)
    423     r0 = pointer to the residual energy (Word32)
    424     dtx  = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag)
    425     pOverflow = Pointer to overflow (Flag)
    426 
    427  Outputs:
    428     cor_max contains the newly calculated normalized correlation of the
    429       selected lag
    430     rmax contains the newly calculated max(<s[i]*s[j]>)
    431     r0 contains the newly calculated residual energy
    432     pOverflow -> 1 if the math functions called by this routine saturate.
    433 
    434  Returns:
    435     p_max = lag of the max correlation found (Word16)
    436 
    437  Global Variables Used:
    438     None.
    439 
    440  Local Variables Needed:
    441     None.
    442 
    443 ------------------------------------------------------------------------------
    444  FUNCTION DESCRIPTION
    445 
    446  This function finds the lag that has maximum correlation of scal_sig[] in a
    447  given delay range.
    448  The correlation is given by
    449     cor[t] = <scal_sig[n],scal_sig[n-t]>,  t=lag_min,...,lag_max
    450  The functions outputs the maximum correlation after normalization and the
    451  corresponding lag.
    452 
    453 ------------------------------------------------------------------------------
    454  REQUIREMENTS
    455 
    456  None.
    457 
    458 ------------------------------------------------------------------------------
    459  REFERENCES
    460 
    461  p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    462 
    463 ------------------------------------------------------------------------------
    464  PSEUDO-CODE
    465 
    466 static Word16 Lag_max ( // o : lag found
    467     vadState *vadSt,    // i/o : VAD state struct
    468     Word32 corr[],      // i   : correlation vector.
    469     Word16 scal_sig[],  // i : scaled signal.
    470     Word16 L_frame,     // i : length of frame to compute pitch
    471     Word16 lag_max,     // i : maximum lag
    472     Word16 lag_min,     // i : minimum lag
    473     Word16 old_lag,     // i : old open-loop lag
    474     Word16 *cor_max,    // o : normalized correlation of selected lag
    475     Word16 wght_flg,    // i : is weighting function used
    476     Word16 *gain_flg,   // o : open-loop flag
    477     Flag dtx            // i   : dtx flag; use dtx=1, do not use dtx=0
    478     )
    479 {
    480     Word16 i, j;
    481     Word16 *p, *p1;
    482     Word32 max, t0;
    483     Word16 t0_h, t0_l;
    484     Word16 p_max;
    485     const Word16 *ww, *we;
    486     Word32 t1;
    487 
    488     ww = &corrweight[250];
    489     we = &corrweight[123 + lag_max - old_lag];
    490 
    491     max = MIN_32;
    492     p_max = lag_max;
    493 
    494     for (i = lag_max; i >= lag_min; i--)
    495     {
    496        t0 = corr[-i];
    497 
    498        // Weighting of the correlation function.
    499        L_Extract (corr[-i], &t0_h, &t0_l);
    500        t0 = Mpy_32_16 (t0_h, t0_l, *ww);
    501        ww--;
    502        if (wght_flg > 0) {
    503           // Weight the neighbourhood of the old lag
    504           L_Extract (t0, &t0_h, &t0_l);
    505           t0 = Mpy_32_16 (t0_h, t0_l, *we);
    506           we--;
    507        }
    508 
    509        if (L_sub (t0, max) >= 0)
    510        {
    511           max = t0;
    512           p_max = i;
    513        }
    514     }
    515 
    516     p  = &scal_sig[0];
    517     p1 = &scal_sig[-p_max];
    518     t0 = 0;
    519     t1 = 0;
    520 
    521     for (j = 0; j < L_frame; j++, p++, p1++)
    522     {
    523        t0 = L_mac (t0, *p, *p1);
    524        t1 = L_mac (t1, *p1, *p1);
    525     }
    526 
    527     if (dtx)
    528     {  // no test() call since this if is only in simulation env
    529 #ifdef VAD2
    530        vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0);   // Save max correlation
    531        vadSt->L_R0 =   L_add(vadSt->L_R0, t1);        // Save max energy
    532 #else
    533        // update and detect tone
    534        vad_tone_detection_update (vadSt, 0);
    535        vad_tone_detection (vadSt, t0, t1);
    536 #endif
    537     }
    538 
    539     // gain flag is set according to the open_loop gain
    540     // is t2/t1 > 0.4 ?
    541     *gain_flg = pv_round(L_msu(t0, pv_round(t1), 13107));
    542 
    543     *cor_max = 0;
    544 
    545     return (p_max);
    546 }
    547 
    548 ------------------------------------------------------------------------------
    549  RESOURCES USED [optional]
    550 
    551  When the code is written for a specific target processor the
    552  the resources used should be documented below.
    553 
    554  HEAP MEMORY USED: x bytes
    555 
    556  STACK MEMORY USED: x bytes
    557 
    558  CLOCK CYCLES: (cycle count equation for this function) + (variable
    559                 used to represent cycle count for each subroutine
    560                 called)
    561      where: (cycle count variable) = cycle count for [subroutine
    562                                      name]
    563 
    564 ------------------------------------------------------------------------------
    565  CAUTION [optional]
    566  [State any special notes, constraints or cautions for users of this function]
    567 
    568 ------------------------------------------------------------------------------
    569 */
    570 
    571 static Word16 Lag_max(  /* o : lag found                               */
    572     vadState *vadSt,    /* i/o : VAD state struct                      */
    573     Word32 corr[],      /* i   : correlation vector.                   */
    574     Word16 scal_sig[],  /* i : scaled signal.                          */
    575     Word16 L_frame,     /* i : length of frame to compute pitch        */
    576     Word16 lag_max,     /* i : maximum lag                             */
    577     Word16 lag_min,     /* i : minimum lag                             */
    578     Word16 old_lag,     /* i : old open-loop lag                       */
    579     Word16 *cor_max,    /* o : normalized correlation of selected lag  */
    580     Word16 wght_flg,    /* i : is weighting function used              */
    581     Word16 *gain_flg,   /* o : open-loop flag                          */
    582     Flag dtx,           /* i : dtx flag; use dtx=1, do not use dtx=0   */
    583     Flag   *pOverflow   /* o : overflow flag                           */
    584 )
    585 {
    586     Word16 i;
    587     Word16 j;
    588     Word16 *p;
    589     Word16 *p1;
    590     Word32 max;
    591     Word32 t0;
    592     Word16 t0_h;
    593     Word16 t0_l;
    594     Word16 p_max;
    595     const Word16 *ww;
    596     const Word16 *we;
    597     Word32 t1;
    598     Word16 temp;
    599 
    600     ww = &corrweight[250];
    601     we = &corrweight[123 + lag_max - old_lag];
    602 
    603     max = MIN_32;
    604     p_max = lag_max;
    605 
    606     for (i = lag_max; i >= lag_min; i--)
    607     {
    608         t0 = corr[-i];
    609 
    610         /* Weighting of the correlation function.   */
    611         L_Extract(corr[-i], &t0_h, &t0_l, pOverflow);
    612         t0 = Mpy_32_16(t0_h, t0_l, *ww, pOverflow);
    613         ww--;
    614         if (wght_flg > 0)
    615         {
    616             /* Weight the neighbourhood of the old lag. */
    617             L_Extract(t0, &t0_h, &t0_l, pOverflow);
    618             t0 = Mpy_32_16(t0_h, t0_l, *we, pOverflow);
    619             we--;
    620         }
    621 
    622         /*       if (L_sub (t0, max) >= 0) */
    623         if (t0 >= max)
    624         {
    625             max = t0;
    626             p_max = i;
    627         }
    628     }
    629     p  = &scal_sig[0];
    630     p1 = &scal_sig[-p_max];
    631     t0 = 0;
    632     t1 = 0;
    633 
    634     for (j = 0; j < L_frame; j++, p++, p1++)
    635     {
    636         t0 = L_mac(t0, *p, *p1, pOverflow);
    637         t1 = L_mac(t1, *p1, *p1, pOverflow);
    638     }
    639 
    640     if (dtx)
    641     {  /* no test() call since this if is only in simulation env */
    642 #ifdef VAD2
    643         /* Save max correlation */
    644         vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0, pOverflow);
    645         /* Save max energy */
    646         vadSt->L_R0 =   L_add(vadSt->L_R0, t1, pOverflow);
    647 #else
    648         /* update and detect tone */
    649         vad_tone_detection_update(vadSt, 0, pOverflow);
    650         vad_tone_detection(vadSt, t0, t1, pOverflow);
    651 #endif
    652     }
    653 
    654     /* gain flag is set according to the open_loop gain */
    655     /* is t2/t1 > 0.4 ? */
    656     temp = pv_round(t1, pOverflow);
    657     t1 = L_msu(t0, temp, 13107, pOverflow);
    658     *gain_flg = pv_round(t1, pOverflow);
    659 
    660     *cor_max = 0;
    661 
    662     return (p_max);
    663 }
    664 /*----------------------------------------------------------------------------
    665 ; End Function: Lag_max
    666 ----------------------------------------------------------------------------*/
    667 
    668 /*
    669 ------------------------------------------------------------------------------
    670  FUNCTION NAME: Pitch_ol_wgh
    671 ------------------------------------------------------------------------------
    672  INPUT AND OUTPUT DEFINITIONS
    673 
    674  Inputs:
    675     st = pointer to pitchOLWghtState structure
    676     vadSt = pointer to a vadState structure
    677     signal = pointer to buffer of signal used to compute the open loop
    678          pitch where signal[-pit_max] to signal[-1] should be known
    679     pit_min = 16 bit value specifies the minimum pitch lag
    680     pit_max = 16 bit value specifies the maximum pitch lag
    681     L_frame = 16 bit value specifies the length of frame to compute pitch
    682     old_lags = pointer to history with old stored Cl lags (Word16)
    683     ol_gain_flg = pointer to OL gain flag (Word16)
    684     idx = 16 bit value specifies the frame index
    685     dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0
    686     pOverflow = pointer to Overflow indicator (Flag)
    687  Outputs
    688     st = The pitchOLWghtState may be modified
    689     vadSt = The vadSt state structure may be modified.
    690     pOverflow -> 1 if the math functions invoked by this routine saturate.
    691 
    692  Returns:
    693     p_max1 = 16 bit value representing the open loop pitch lag.
    694 
    695  Global Variables Used:
    696     None.
    697 
    698  Local Variables Needed:
    699     None.
    700 
    701 ------------------------------------------------------------------------------
    702  FUNCTION DESCRIPTION
    703 
    704  This function performs an open-loop pitch search with weighting
    705 ------------------------------------------------------------------------------
    706  REQUIREMENTS
    707 
    708  None.
    709 
    710 ------------------------------------------------------------------------------
    711  REFERENCES
    712 
    713  pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    714 
    715 ------------------------------------------------------------------------------
    716  PSEUDO-CODE
    717 
    718 Word16 Pitch_ol_wgh (     // o   : open loop pitch lag
    719     pitchOLWghtState *st, // i/o : State struct
    720     vadState *vadSt,      // i/o : VAD state struct/
    721     Word16 signal[],      // i   : signal used to compute the open loop pitch
    722                           //       signal[-pit_max] to signal[-1] should be known
    723     Word16 pit_min,       // i   : minimum pitch lag
    724     Word16 pit_max,       // i   : maximum pitch lag
    725     Word16 L_frame,       // i   : length of frame to compute pitch
    726     Word16 old_lags[],    // i   : history with old stored Cl lags
    727     Word16 ol_gain_flg[], // i   : OL gain flag
    728     Word16 idx,           // i   : index
    729     Flag dtx              // i   : dtx flag; use dtx=1, do not use dtx=0
    730     )
    731 {
    732     Word16 i;
    733     Word16 max1;
    734     Word16 p_max1;
    735     Word32 t0;
    736 #ifndef VAD2
    737     Word16 corr_hp_max;
    738 #endif
    739     Word32 corr[PIT_MAX+1], *corr_ptr;
    740 
    741     // Scaled signal
    742     Word16 scaled_signal[PIT_MAX + L_FRAME];
    743     Word16 *scal_sig;
    744 
    745     scal_sig = &scaled_signal[pit_max];
    746 
    747     t0 = 0L;
    748     for (i = -pit_max; i < L_frame; i++)
    749     {
    750         t0 = L_mac (t0, signal[i], signal[i]);
    751     }
    752     //
    753     // Scaling of input signal
    754     //
    755     //   if Overflow        -> scal_sig[i] = signal[i]>>2
    756     //   else if t0 < 1^22  -> scal_sig[i] = signal[i]<<2
    757     //   else               -> scal_sig[i] = signal[i]
    758 
    759     //
    760     //  Verification for risk of overflow.
    761     //
    762 
    763     // Test for overflow
    764     if (L_sub (t0, MAX_32) == 0L)
    765     {
    766         for (i = -pit_max; i < L_frame; i++)
    767         {
    768             scal_sig[i] = shr (signal[i], 3);
    769         }
    770     }
    771     else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0)
    772     {
    773         for (i = -pit_max; i < L_frame; i++)
    774         {
    775             scal_sig[i] = shl (signal[i], 3);
    776         }
    777     }
    778     else
    779     {
    780         for (i = -pit_max; i < L_frame; i++)
    781         {
    782             scal_sig[i] = signal[i];
    783         }
    784     }
    785 
    786     // calculate all coreelations of scal_sig, from pit_min to pit_max
    787     corr_ptr = &corr[pit_max];
    788     comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr);
    789 
    790     p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
    791                       st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
    792                       dtx);
    793 
    794     if (ol_gain_flg[idx] > 0)
    795     {
    796        // Calculate 5-point median of previous lag
    797        for (i = 4; i > 0; i--) // Shift buffer
    798        {
    799           old_lags[i] = old_lags[i-1];
    800        }
    801        old_lags[0] = p_max1;
    802        st->old_T0_med = gmed_n (old_lags, 5);
    803        st->ada_w = 32767; // Q15 = 1.0
    804     }
    805     else
    806     {
    807        st->old_T0_med = p_max1;
    808        st->ada_w = mult(st->ada_w, 29491);      // = ada_w = ada_w * 0.9
    809     }
    810 
    811     if (sub(st->ada_w, 9830) < 0)  // ada_w - 0.3
    812     {
    813        st->wght_flg = 0;
    814     }
    815     else
    816     {
    817        st->wght_flg = 1;
    818     }
    819 
    820 #ifndef VAD2
    821     if (dtx)
    822     {  // no test() call since this if is only in simulation env
    823        if (sub(idx, 1) == 0)
    824        {
    825           // calculate max high-passed filtered correlation of all lags
    826           hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max);
    827 
    828           // update complex background detector
    829           vad_complex_detection_update(vadSt, corr_hp_max);
    830        }
    831     }
    832 #endif
    833 
    834     return (p_max1);
    835 }
    836 
    837 ------------------------------------------------------------------------------
    838  RESOURCES USED [optional]
    839 
    840  When the code is written for a specific target processor the
    841  the resources used should be documented below.
    842 
    843  HEAP MEMORY USED: x bytes
    844 
    845  STACK MEMORY USED: x bytes
    846 
    847  CLOCK CYCLES: (cycle count equation for this function) + (variable
    848                 used to represent cycle count for each subroutine
    849                 called)
    850      where: (cycle count variable) = cycle count for [subroutine
    851                                      name]
    852 
    853 ------------------------------------------------------------------------------
    854  CAUTION [optional]
    855  [State any special notes, constraints or cautions for users of this function]
    856 
    857 ------------------------------------------------------------------------------
    858 */
    859 
    860 Word16 Pitch_ol_wgh(      /* o   : open loop pitch lag                            */
    861     pitchOLWghtState *st, /* i/o : State struct                                   */
    862     vadState *vadSt,      /* i/o : VAD state struct                               */
    863     Word16 signal[],      /* i   : signal used to compute the open loop pitch     */
    864     /*       signal[-pit_max] to signal[-1] should be known */
    865     Word16 pit_min,       /* i   : minimum pitch lag                              */
    866     Word16 pit_max,       /* i   : maximum pitch lag                              */
    867     Word16 L_frame,       /* i   : length of frame to compute pitch               */
    868     Word16 old_lags[],    /* i   : history with old stored Cl lags                */
    869     Word16 ol_gain_flg[], /* i   : OL gain flag                                   */
    870     Word16 idx,           /* i   : index                                          */
    871     Flag dtx,             /* i   : dtx flag; use dtx=1, do not use dtx=0          */
    872     Flag   *pOverflow     /* o   : overflow flag                                  */
    873 )
    874 {
    875     Word16 i;
    876     Word16 max1;
    877     Word16 p_max1;
    878     Word32 t0;
    879 #ifndef VAD2
    880     Word16 corr_hp_max;
    881 #endif
    882     Word32 corr[PIT_MAX+1], *corr_ptr;
    883 
    884     /* Scaled signal */
    885     Word16 scaled_signal[PIT_MAX + L_FRAME];
    886     Word16 *scal_sig;
    887 
    888     scal_sig = &scaled_signal[pit_max];
    889 
    890     t0 = 0L;
    891     for (i = -pit_max; i < L_frame; i++)
    892     {
    893         t0 = L_mac(t0, signal[i], signal[i], pOverflow);
    894     }
    895     /*--------------------------------------------------------*
    896      * Scaling of input signal.                               *
    897      *                                                        *
    898      *   if Overflow        -> scal_sig[i] = signal[i]>>2     *
    899      *   else if t0 < 1^22  -> scal_sig[i] = signal[i]<<2     *
    900      *   else               -> scal_sig[i] = signal[i]        *
    901      *--------------------------------------------------------*/
    902 
    903     /*--------------------------------------------------------*
    904      *  Verification for risk of overflow.                    *
    905      *--------------------------------------------------------*/
    906 
    907     /* Test for overflow */
    908     if (L_sub(t0, MAX_32, pOverflow) == 0L)
    909     {
    910         for (i = -pit_max; i < L_frame; i++)
    911         {
    912             scal_sig[i] = shr(signal[i], 3, pOverflow);
    913         }
    914     }
    915     else if (L_sub(t0, (Word32) 1048576L, pOverflow) < (Word32) 0)
    916     {
    917         for (i = -pit_max; i < L_frame; i++)
    918         {
    919             scal_sig[i] = shl(signal[i], 3, pOverflow);
    920         }
    921     }
    922     else
    923     {
    924         for (i = -pit_max; i < L_frame; i++)
    925         {
    926             scal_sig[i] = signal[i];
    927         }
    928     }
    929 
    930     /* calculate all coreelations of scal_sig, from pit_min to pit_max */
    931     corr_ptr = &corr[pit_max];
    932     comp_corr(scal_sig, L_frame, pit_max, pit_min, corr_ptr);
    933 
    934     p_max1 = Lag_max(vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
    935                      st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
    936                      dtx, pOverflow);
    937 
    938     if (ol_gain_flg[idx] > 0)
    939     {
    940         /* Calculate 5-point median of previous lags */
    941         for (i = 4; i > 0; i--) /* Shift buffer */
    942         {
    943             old_lags[i] = old_lags[i-1];
    944         }
    945         old_lags[0] = p_max1;
    946         st->old_T0_med = gmed_n(old_lags, 5);
    947         st->ada_w = 32767; /* Q15 = 1.0 */
    948     }
    949     else
    950     {
    951         st->old_T0_med = p_max1;
    952         /* = ada_w = ada_w * 0.9 */
    953         st->ada_w = mult(st->ada_w, 29491, pOverflow);
    954     }
    955 
    956     if (sub(st->ada_w, 9830, pOverflow) < 0)  /* ada_w - 0.3 */
    957     {
    958         st->wght_flg = 0;
    959     }
    960     else
    961     {
    962         st->wght_flg = 1;
    963     }
    964 
    965 #ifndef VAD2
    966     if (dtx)
    967     {  /* no test() call since this if is only in simulation env */
    968         if (sub(idx, 1, pOverflow) == 0)
    969         {
    970             /* calculate max high-passed filtered correlation of all lags */
    971             hp_max(corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max, pOverflow);
    972 
    973             /* update complex background detector */
    974             vad_complex_detection_update(vadSt, corr_hp_max);
    975         }
    976     }
    977 #endif
    978 
    979     return (p_max1);
    980 }
    981 
    982 /*----------------------------------------------------------------------------
    983 ; End Function: Pitch_ol_wgh
    984 ----------------------------------------------------------------------------*/
    985 
    986 
    987 
    988 
    989 
    990