/*
 ** 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;

}



