/*
 ** 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(voround(R1), voround(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;

}



