Home | History | Annotate | Download | only in src
      1 /*
      2  ** Copyright 2003-2010, VisualOn, Inc.
      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 express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 
     17 /***********************************************************************
     18 *      File: p_med_ol.c                                                *
     19 *                                                                      *
     20 *      Description: Compute the open loop pitch lag                    *
     21 *               output: open loop pitch lag                        *
     22 ************************************************************************/
     23 
     24 #include "typedef.h"
     25 #include "basic_op.h"
     26 #include "acelp.h"
     27 #include "oper_32b.h"
     28 #include "math_op.h"
     29 #include "p_med_ol.tab"
     30 
     31 Word16 Pitch_med_ol(
     32            Word16      wsp[],        /*   i: signal used to compute the open loop pitch*/
     33                                      /*      wsp[-pit_max] to wsp[-1] should be known */
     34            Coder_State *st,          /* i/o: codec global structure */
     35            Word16      L_frame       /*   i: length of frame to compute pitch */
     36         )
     37 {
     38     Word16 Tm;
     39     Word16 hi, lo;
     40     Word16 *ww, *we, *hp_wsp;
     41     Word16 exp_R0, exp_R1, exp_R2;
     42     Word32 i, j, max, R0, R1, R2;
     43     Word16 *p1, *p2;
     44     Word16 L_min = 17;                   /* minimum pitch lag: PIT_MIN / OPL_DECIM */
     45     Word16 L_max = 115;                  /* maximum pitch lag: PIT_MAX / OPL_DECIM */
     46     Word16 L_0 = st->old_T0_med;         /* old open-loop pitch */
     47     Word16 *gain = &(st->ol_gain);       /* normalize correlation of hp_wsp for the lag */
     48     Word16 *hp_wsp_mem = st->hp_wsp_mem; /* memory of the hypass filter for hp_wsp[] (lg = 9)*/
     49     Word16 *old_hp_wsp = st->old_hp_wsp; /* hypass wsp[] */
     50     Word16 wght_flg = st->ol_wght_flg;   /* is weighting function used */
     51 
     52     ww = &corrweight[198];
     53     we = &corrweight[98 + L_max - L_0];
     54 
     55     max = MIN_32;
     56     Tm = 0;
     57     for (i = L_max; i > L_min; i--)
     58     {
     59         /* Compute the correlation */
     60         R0 = 0;
     61         p1 = wsp;
     62         p2 = &wsp[-i];
     63         for (j = 0; j < L_frame; j+=4)
     64         {
     65             R0 += vo_L_mult((*p1++), (*p2++));
     66             R0 += vo_L_mult((*p1++), (*p2++));
     67             R0 += vo_L_mult((*p1++), (*p2++));
     68             R0 += vo_L_mult((*p1++), (*p2++));
     69         }
     70         /* Weighting of the correlation function.   */
     71         hi = R0>>16;
     72         lo = (R0 & 0xffff)>>1;
     73 
     74         R0 = Mpy_32_16(hi, lo, *ww);
     75         ww--;
     76 
     77         if ((L_0 > 0) && (wght_flg > 0))
     78         {
     79             /* Weight the neighbourhood of the old lag. */
     80             hi = R0>>16;
     81             lo = (R0 & 0xffff)>>1;
     82             R0 = Mpy_32_16(hi, lo, *we);
     83             we--;
     84         }
     85         if(R0 >= max)
     86         {
     87             max = R0;
     88             Tm = i;
     89         }
     90     }
     91 
     92     /* Hypass the wsp[] vector */
     93     hp_wsp = old_hp_wsp + L_max;
     94     Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem);
     95 
     96     /* Compute normalize correlation at delay Tm */
     97     R0 = 0;
     98     R1 = 0;
     99     R2 = 0;
    100     p1 = hp_wsp;
    101     p2 = hp_wsp - Tm;
    102     for (j = 0; j < L_frame; j+=4)
    103     {
    104         R2 += vo_mult32(*p1, *p1);
    105         R1 += vo_mult32(*p2, *p2);
    106         R0 += vo_mult32(*p1++, *p2++);
    107         R2 += vo_mult32(*p1, *p1);
    108         R1 += vo_mult32(*p2, *p2);
    109         R0 += vo_mult32(*p1++, *p2++);
    110         R2 += vo_mult32(*p1, *p1);
    111         R1 += vo_mult32(*p2, *p2);
    112         R0 += vo_mult32(*p1++, *p2++);
    113         R2 += vo_mult32(*p1, *p1);
    114         R1 += vo_mult32(*p2, *p2);
    115         R0 += vo_mult32(*p1++, *p2++);
    116     }
    117     R0 = R0 <<1;
    118     R1 = (R1 <<1) + 1L;
    119     R2 = (R2 <<1) + 1L;
    120     /* gain = R0/ sqrt(R1*R2) */
    121 
    122     exp_R0 = norm_l(R0);
    123     R0 = (R0 << exp_R0);
    124 
    125     exp_R1 = norm_l(R1);
    126     R1 = (R1 << exp_R1);
    127 
    128     exp_R2 = norm_l(R2);
    129     R2 = (R2 << exp_R2);
    130 
    131 
    132     R1 = vo_L_mult(voround(R1), voround(R2));
    133 
    134     i = norm_l(R1);
    135     R1 = (R1 << i);
    136 
    137     exp_R1 += exp_R2;
    138     exp_R1 += i;
    139     exp_R1 = 62 - exp_R1;
    140 
    141     Isqrt_n(&R1, &exp_R1);
    142 
    143     R0 = vo_L_mult(voround(R0), voround(R1));
    144     exp_R0 = 31 - exp_R0;
    145     exp_R0 += exp_R1;
    146 
    147     *gain = vo_round(L_shl(R0, exp_R0));
    148 
    149     /* Shitf hp_wsp[] for next frame */
    150 
    151     for (i = 0; i < L_max; i++)
    152     {
    153         old_hp_wsp[i] = old_hp_wsp[i + L_frame];
    154     }
    155 
    156     return (Tm);
    157 }
    158 
    159 /************************************************************************
    160 *  Function: median5                                                    *
    161 *                                                                       *
    162 *      Returns the median of the set {X[-2], X[-1],..., X[2]},          *
    163 *      whose elements are 16-bit integers.                              *
    164 *                                                                       *
    165 *  Input:                                                               *
    166 *      X[-2:2]   16-bit integers.                                       *
    167 *                                                                       *
    168 *  Return:                                                              *
    169 *      The median of {X[-2], X[-1],..., X[2]}.                          *
    170 ************************************************************************/
    171 
    172 Word16 median5(Word16 x[])
    173 {
    174     Word16 x1, x2, x3, x4, x5;
    175     Word16 tmp;
    176 
    177     x1 = x[-2];
    178     x2 = x[-1];
    179     x3 = x[0];
    180     x4 = x[1];
    181     x5 = x[2];
    182 
    183     if (x2 < x1)
    184     {
    185         tmp = x1;
    186         x1 = x2;
    187         x2 = tmp;
    188     }
    189     if (x3 < x1)
    190     {
    191         tmp = x1;
    192         x1 = x3;
    193         x3 = tmp;
    194     }
    195     if (x4 < x1)
    196     {
    197         tmp = x1;
    198         x1 = x4;
    199         x4 = tmp;
    200     }
    201     if (x5 < x1)
    202     {
    203         x5 = x1;
    204     }
    205     if (x3 < x2)
    206     {
    207         tmp = x2;
    208         x2 = x3;
    209         x3 = tmp;
    210     }
    211     if (x4 < x2)
    212     {
    213         tmp = x2;
    214         x2 = x4;
    215         x4 = tmp;
    216     }
    217     if (x5 < x2)
    218     {
    219         x5 = x2;
    220     }
    221     if (x4 < x3)
    222     {
    223         x3 = x4;
    224     }
    225     if (x5 < x3)
    226     {
    227         x3 = x5;
    228     }
    229     return (x3);
    230 }
    231 
    232 
    233 Word16 Med_olag(                           /* output : median of  5 previous open-loop lags       */
    234         Word16 prev_ol_lag,                /* input  : previous open-loop lag                     */
    235         Word16 old_ol_lag[5]
    236            )
    237 {
    238     Word32 i;
    239 
    240     /* Use median of 5 previous open-loop lags as old lag */
    241 
    242     for (i = 4; i > 0; i--)
    243     {
    244         old_ol_lag[i] = old_ol_lag[i - 1];
    245     }
    246 
    247     old_ol_lag[0] = prev_ol_lag;
    248 
    249     i = median5(&old_ol_lag[2]);
    250 
    251     return i;
    252 
    253 }
    254 
    255 
    256 
    257