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  Filename: /audio/gsm_amr/c/src/hp_max.c
     35 
     36      Date: 02/01/2002
     37 
     38 ------------------------------------------------------------------------------
     39  REVISION HISTORY
     40 
     41  Description:  Replaced "int" and/or "char" with OSCL defined types.
     42 
     43  Description:
     44 
     45 ------------------------------------------------------------------------------
     46 */
     47 
     48 /*----------------------------------------------------------------------------
     49 ; INCLUDES
     50 ----------------------------------------------------------------------------*/
     51 #include    "hp_max.h"
     52 #include    "basic_op.h"
     53 #include    "cnst.h"
     54 
     55 /*----------------------------------------------------------------------------
     56 ; MACROS
     57 ; [Define module specific macros here]
     58 ----------------------------------------------------------------------------*/
     59 
     60 /*----------------------------------------------------------------------------
     61 ; DEFINES
     62 ; [Include all pre-processor statements here. Include conditional
     63 ; compile variables also.]
     64 ----------------------------------------------------------------------------*/
     65 
     66 /*----------------------------------------------------------------------------
     67 ; LOCAL FUNCTION DEFINITIONS
     68 ; [List function prototypes here]
     69 ----------------------------------------------------------------------------*/
     70 
     71 /*----------------------------------------------------------------------------
     72 ; LOCAL VARIABLE DEFINITIONS
     73 ; [Variable declaration - defined here and used outside this module]
     74 ----------------------------------------------------------------------------*/
     75 
     76 /*
     77 ------------------------------------------------------------------------------
     78  FUNCTION NAME: hp_max
     79 ------------------------------------------------------------------------------
     80  INPUT AND OUTPUT DEFINITIONS
     81 
     82  Inputs:
     83     corr[] = correlation vector (Word16)
     84     scal_sig[] = scaled signal vector (Word16)
     85     L_frame = length of frame to compute pitch (Word16
     86     lag_max = maximum lag (Word16)
     87     lag_min = minimum lag (Word16)
     88     cor_hp_max = pointer to max high-pass filtered norm. correlation (Word16)
     89     pOverflow = pointer to overflow (Flag)
     90 
     91  Outputs:
     92     cor_hp_max contains max high-pass filtered norm. correlation (Word16)
     93     pOverflow -> 1 if the maximum correlation computation resulted in overflow
     94 
     95  Returns:
     96     0 (Word16)
     97 
     98  Global Variables Used:
     99     None
    100 
    101  Local Variables Needed:
    102     None
    103 
    104 ------------------------------------------------------------------------------
    105  FUNCTION DESCRIPTION
    106 
    107  This function finds the maximum high-pass filtered correlation of scal_sig[]
    108  in a given delay range.
    109 
    110  The correlation is given by
    111     corr[t] = <scal_sig[n],scal_sig[n-t]>,  t=lag_min,...,lag_max
    112  The functions outputs the maximum high-pass filtered correlation after
    113  normalization.
    114 
    115 ------------------------------------------------------------------------------
    116  REQUIREMENTS
    117 
    118  None
    119 
    120 ------------------------------------------------------------------------------
    121  REFERENCES
    122 
    123  [1] hp_max.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    124 
    125 ------------------------------------------------------------------------------
    126  PSEUDO-CODE
    127 
    128 Word16 hp_max (
    129     Word32 corr[],      // i   : correlation vector
    130     Word16 scal_sig[],  // i   : scaled signal
    131     Word16 L_frame,     // i   : length of frame to compute pitch
    132     Word16 lag_max,     // i   : maximum lag
    133     Word16 lag_min,     // i   : minimum lag
    134     Word16 *cor_hp_max) // o   : max high-pass filtered norm. correlation
    135 {
    136     Word16 i;
    137     Word16 *p, *p1;
    138     Word32 max, t0, t1;
    139     Word16 max16, t016, cor_max;
    140     Word16 shift, shift1, shift2;
    141 
    142     max = MIN_32;
    143     t0 = 0L;
    144 * The reference ETSI code uses a global flag for Overflow inside the math functions
    145 * saturate(). In the actual implementation a pointer to Overflow flag is passed in
    146 * as a parameter to the function
    147 
    148     for (i = lag_max-1; i > lag_min; i--)
    149     {
    150        // high-pass filtering
    151        t0 = L_sub (L_sub(L_shl(corr[-i], 1), corr[-i-1]), corr[-i+1]);
    152        t0 = L_abs (t0);
    153 
    154        if (L_sub (t0, max) >= 0)
    155        {
    156           max = t0;
    157        }
    158     }
    159 
    160     // compute energy
    161     p = scal_sig;
    162     p1 = &scal_sig[0];
    163     t0 = 0L;
    164     for (i = 0; i < L_frame; i++, p++, p1++)
    165     {
    166        t0 = L_mac (t0, *p, *p1);
    167     }
    168 
    169     p = scal_sig;
    170     p1 = &scal_sig[-1];
    171     t1 = 0L;
    172     for (i = 0; i < L_frame; i++, p++, p1++)
    173     {
    174        t1 = L_mac (t1, *p, *p1);
    175     }
    176 
    177     // high-pass filtering
    178     t0 = L_sub(L_shl(t0, 1), L_shl(t1, 1));
    179     t0 = L_abs (t0);
    180 
    181     // max/t0
    182     shift1 = sub(norm_l(max), 1);
    183     max16  = extract_h(L_shl(max, shift1));
    184     shift2 = norm_l(t0);
    185     t016 =  extract_h(L_shl(t0, shift2));
    186 
    187     if (t016 != 0)
    188     {
    189        cor_max = div_s(max16, t016);
    190     }
    191     else
    192     {
    193        cor_max = 0;
    194     }
    195 
    196     shift = sub(shift1, shift2);
    197 
    198     if (shift >= 0)
    199     {
    200        *cor_hp_max = shr(cor_max, shift); // Q15
    201     }
    202     else
    203     {
    204        *cor_hp_max = shl(cor_max, negate(shift)); // Q15
    205     }
    206 
    207     return 0;
    208 }
    209 
    210 
    211 ------------------------------------------------------------------------------
    212  RESOURCES USED [optional]
    213 
    214  When the code is written for a specific target processor the
    215  the resources used should be documented below.
    216 
    217  HEAP MEMORY USED: x bytes
    218 
    219  STACK MEMORY USED: x bytes
    220 
    221  CLOCK CYCLES: (cycle count equation for this function) + (variable
    222                 used to represent cycle count for each subroutine
    223                 called)
    224      where: (cycle count variable) = cycle count for [subroutine
    225                                      name]
    226 
    227 ------------------------------------------------------------------------------
    228  CAUTION [optional]
    229  [State any special notes, constraints or cautions for users of this function]
    230 
    231 ------------------------------------------------------------------------------
    232 */
    233 
    234 /*----------------------------------------------------------------------------
    235 ; FUNCTION CODE
    236 ----------------------------------------------------------------------------*/
    237 Word16 hp_max(
    238     Word32 corr[],      /* i   : correlation vector.                      */
    239     Word16 scal_sig[],  /* i   : scaled signal.                           */
    240     Word16 L_frame,     /* i   : length of frame to compute pitch         */
    241     Word16 lag_max,     /* i   : maximum lag                              */
    242     Word16 lag_min,     /* i   : minimum lag                              */
    243     Word16 *cor_hp_max, /* o   : max high-pass filtered norm. correlation */
    244     Flag   *pOverflow   /* i/o : overflow Flag                            */
    245 )
    246 {
    247     Word16 i;
    248     Word16 *p, *p1;
    249     Word32 max, t0, t1;
    250     Word16 max16, t016, cor_max;
    251     Word16 shift, shift1, shift2;
    252     Word32 L_temp;
    253 
    254     max = MIN_32;
    255     t0 = 0L;
    256 
    257     for (i = lag_max - 1; i > lag_min; i--)
    258     {
    259         /* high-pass filtering */
    260         t0 = L_shl(corr[-i], 1, pOverflow);
    261         L_temp = L_sub(t0, corr[-i-1], pOverflow);
    262         t0 = L_sub(L_temp, corr[-i+1], pOverflow);
    263         t0 = L_abs(t0);
    264 
    265         if (t0 >= max)
    266         {
    267             max = t0;
    268         }
    269     }
    270 
    271     /* compute energy */
    272     p = scal_sig;
    273     p1 = &scal_sig[0];
    274     t0 = 0L;
    275     for (i = 0; i < L_frame; i++, p++, p1++)
    276     {
    277         t0 = L_mac(t0, *p, *p1, pOverflow);
    278     }
    279 
    280     p = scal_sig;
    281     p1 = &scal_sig[-1];
    282     t1 = 0L;
    283     for (i = 0; i < L_frame; i++, p++, p1++)
    284     {
    285         t1 = L_mac(t1, *p, *p1, pOverflow);
    286     }
    287 
    288     /* high-pass filtering */
    289     L_temp = L_shl(t0, 1, pOverflow);
    290     t1 = L_shl(t1, 1, pOverflow);
    291     t0 = L_sub(L_temp, t1, pOverflow);
    292     t0 = L_abs(t0);
    293 
    294     /* max/t0 */
    295     /*  shift1 = sub(norm_l(max), 1);
    296         max16  = extract_h(L_shl(max, shift1));
    297         shift2 = norm_l(t0);
    298         t016 =  extract_h(L_shl(t0, shift2));   */
    299 
    300     t016 = norm_l(max);
    301     shift1 = sub(t016, 1, pOverflow);
    302 
    303     L_temp = L_shl(max, shift1, pOverflow);
    304     max16  = (Word16)(L_temp >> 16);
    305 
    306     shift2 = norm_l(t0);
    307     L_temp = L_shl(t0, shift2, pOverflow);
    308     t016 = (Word16)(L_temp >> 16);
    309 
    310     if (t016 != 0)
    311     {
    312         cor_max = div_s(max16, t016);
    313     }
    314     else
    315     {
    316         cor_max = 0;
    317     }
    318 
    319     shift = sub(shift1, shift2, pOverflow);
    320 
    321     if (shift >= 0)
    322     {
    323         *cor_hp_max = shr(cor_max, shift, pOverflow); /* Q15 */
    324     }
    325     else
    326     {
    327         *cor_hp_max = shl(cor_max, negate(shift), pOverflow); /* Q15 */
    328     }
    329 
    330     return 0;
    331 }
    332 
    333