/*
 ** Copyright 2003-2010, VisualOn, Inc.
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */

/***********************************************************************
*      File: p_med_ol.c                                                *
*                                                                      *
*      Description: Compute the open loop pitch lag                    *
*               output: open loop pitch lag                        *
************************************************************************/

#include "typedef.h"
#include "basic_op.h"
#include "acelp.h"
#include "oper_32b.h"
#include "math_op.h"
#include "p_med_ol.tab"

Word16 Pitch_med_ol(
           Word16      wsp[],        /*   i: signal used to compute the open loop pitch*/
                                     /*      wsp[-pit_max] to wsp[-1] should be known */
           Coder_State *st,          /* i/o: codec global structure */
           Word16      L_frame       /*   i: length of frame to compute pitch */
        )
{
    Word16 Tm;
    Word16 hi, lo;
    Word16 *ww, *we, *hp_wsp;
    Word16 exp_R0, exp_R1, exp_R2;
    Word32 i, j, max, R0, R1, R2;
    Word16 *p1, *p2;
    Word16 L_min = 17;                   /* minimum pitch lag: PIT_MIN / OPL_DECIM */
    Word16 L_max = 115;                  /* maximum pitch lag: PIT_MAX / OPL_DECIM */
    Word16 L_0 = st->old_T0_med;         /* old open-loop pitch */
    Word16 *gain = &(st->ol_gain);       /* normalize correlation of hp_wsp for the lag */
    Word16 *hp_wsp_mem = st->hp_wsp_mem; /* memory of the hypass filter for hp_wsp[] (lg = 9)*/
    Word16 *old_hp_wsp = st->old_hp_wsp; /* hypass wsp[] */
    Word16 wght_flg = st->ol_wght_flg;   /* is weighting function used */

    ww = &corrweight[198];
    we = &corrweight[98 + L_max - L_0];

    max = MIN_32;
    Tm = 0;
    for (i = L_max; i > L_min; i--)
    {
        /* Compute the correlation */
        R0 = 0;
        p1 = wsp;
        p2 = &wsp[-i];
        for (j = 0; j < L_frame; j+=4)
        {
            R0 += vo_L_mult((*p1++), (*p2++));
            R0 += vo_L_mult((*p1++), (*p2++));
            R0 += vo_L_mult((*p1++), (*p2++));
            R0 += vo_L_mult((*p1++), (*p2++));
        }
        /* Weighting of the correlation function.   */
        hi = R0>>16;
        lo = (R0 & 0xffff)>>1;

        R0 = Mpy_32_16(hi, lo, *ww);
        ww--;

        if ((L_0 > 0) && (wght_flg > 0))
        {
            /* Weight the neighbourhood of the old lag. */
            hi = R0>>16;
            lo = (R0 & 0xffff)>>1;
            R0 = Mpy_32_16(hi, lo, *we);
            we--;
        }
        if(R0 >= max)
        {
            max = R0;
            Tm = i;
        }
    }

    /* Hypass the wsp[] vector */
    hp_wsp = old_hp_wsp + L_max;
    Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem);

    /* Compute normalize correlation at delay Tm */
    R0 = 0;
    R1 = 0;
    R2 = 0;
    p1 = hp_wsp;
    p2 = hp_wsp - Tm;
    for (j = 0; j < L_frame; j+=4)
    {
        R2 += vo_mult32(*p1, *p1);
        R1 += vo_mult32(*p2, *p2);
        R0 += vo_mult32(*p1++, *p2++);
        R2 += vo_mult32(*p1, *p1);
        R1 += vo_mult32(*p2, *p2);
        R0 += vo_mult32(*p1++, *p2++);
        R2 += vo_mult32(*p1, *p1);
        R1 += vo_mult32(*p2, *p2);
        R0 += vo_mult32(*p1++, *p2++);
        R2 += vo_mult32(*p1, *p1);
        R1 += vo_mult32(*p2, *p2);
        R0 += vo_mult32(*p1++, *p2++);
    }
    R0 = R0 <<1;
    R1 = (R1 <<1) + 1L;
    R2 = (R2 <<1) + 1L;
    /* gain = R0/ sqrt(R1*R2) */

    exp_R0 = norm_l(R0);
    R0 = (R0 << exp_R0);

    exp_R1 = norm_l(R1);
    R1 = (R1 << exp_R1);

    exp_R2 = norm_l(R2);
    R2 = (R2 << exp_R2);


    R1 = vo_L_mult(vo_round(R1), vo_round(R2));

    i = norm_l(R1);
    R1 = (R1 << i);

    exp_R1 += exp_R2;
    exp_R1 += i;
    exp_R1 = 62 - exp_R1;

    Isqrt_n(&R1, &exp_R1);

    R0 = vo_L_mult(voround(R0), voround(R1));
    exp_R0 = 31 - exp_R0;
    exp_R0 += exp_R1;

    *gain = vo_round(L_shl(R0, exp_R0));

    /* Shitf hp_wsp[] for next frame */

    for (i = 0; i < L_max; i++)
    {
        old_hp_wsp[i] = old_hp_wsp[i + L_frame];
    }

    return (Tm);
}

/************************************************************************
*  Function: median5                                                    *
*                                                                       *
*      Returns the median of the set {X[-2], X[-1],..., X[2]},          *
*      whose elements are 16-bit integers.                              *
*                                                                       *
*  Input:                                                               *
*      X[-2:2]   16-bit integers.                                       *
*                                                                       *
*  Return:                                                              *
*      The median of {X[-2], X[-1],..., X[2]}.                          *
************************************************************************/

Word16 median5(Word16 x[])
{
    Word16 x1, x2, x3, x4, x5;
    Word16 tmp;

    x1 = x[-2];
    x2 = x[-1];
    x3 = x[0];
    x4 = x[1];
    x5 = x[2];

    if (x2 < x1)
    {
        tmp = x1;
        x1 = x2;
        x2 = tmp;
    }
    if (x3 < x1)
    {
        tmp = x1;
        x1 = x3;
        x3 = tmp;
    }
    if (x4 < x1)
    {
        tmp = x1;
        x1 = x4;
        x4 = tmp;
    }
    if (x5 < x1)
    {
        x5 = x1;
    }
    if (x3 < x2)
    {
        tmp = x2;
        x2 = x3;
        x3 = tmp;
    }
    if (x4 < x2)
    {
        tmp = x2;
        x2 = x4;
        x4 = tmp;
    }
    if (x5 < x2)
    {
        x5 = x2;
    }
    if (x4 < x3)
    {
        x3 = x4;
    }
    if (x5 < x3)
    {
        x3 = x5;
    }
    return (x3);
}


Word16 Med_olag(                           /* output : median of  5 previous open-loop lags       */
        Word16 prev_ol_lag,                /* input  : previous open-loop lag                     */
        Word16 old_ol_lag[5]
           )
{
    Word32 i;

    /* Use median of 5 previous open-loop lags as old lag */

    for (i = 4; i > 0; i--)
    {
        old_ol_lag[i] = old_ol_lag[i - 1];
    }

    old_ol_lag[0] = prev_ol_lag;

    i = median5(&old_ol_lag[2]);

    return i;

}



