/*
 ** 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: gpclip.c                                                     *
*                                                                         *
*      Description:To avoid unstable synthesis on frame erasure, the gain *
*      need to be limited(gain pitch < 1.0) when the following            *
*      case occurs                                                        *
*      a resonance on LPC filter(lp_disp < 60Hz)                          *
*      a good pitch prediction (lp_gp > 0.95)                             *
*                                                                         *   
***************************************************************************/
#include "typedef.h"
#include "basic_op.h"

#define DIST_ISF_MAX    307                /* 120 Hz (6400Hz=16384) */
#define DIST_ISF_THRES  154                /* 60     (6400Hz=16384) */
#define GAIN_PIT_THRES  14746              /* 0.9 in Q14 */
#define GAIN_PIT_MIN    9830               /* 0.6 in Q14 */
#define M               16


void Init_gp_clip(
		Word16 mem[]                          /* (o) : memory of gain of pitch clipping algorithm */
		)
{
	mem[0] = DIST_ISF_MAX;                 
	mem[1] = GAIN_PIT_MIN;                 
}


Word16 Gp_clip(
		Word16 mem[]                          /* (i/o) : memory of gain of pitch clipping algorithm */
	      )
{
	Word16 clip = 0;
	if ((mem[0] < DIST_ISF_THRES) && (mem[1] > GAIN_PIT_THRES))
		clip = 1;                          

	return (clip);
}


void Gp_clip_test_isf(
		Word16 isf[],                         /* (i)   : isf values (in frequency domain)           */
		Word16 mem[]                          /* (i/o) : memory of gain of pitch clipping algorithm */
		)
{
	Word16 dist, dist_min;
	Word32 i;

	dist_min = vo_sub(isf[1], isf[0]);

	for (i = 2; i < M - 1; i++)
	{
		dist = vo_sub(isf[i], isf[i - 1]);
		if(dist < dist_min)
		{
			dist_min = dist;               
		}
	}

	dist = extract_h(L_mac(vo_L_mult(26214, mem[0]), 6554, dist_min));

	if (dist > DIST_ISF_MAX)
	{
		dist = DIST_ISF_MAX;               
	}
	mem[0] = dist;                        

	return;
}


void Gp_clip_test_gain_pit(
		Word16 gain_pit,                      /* (i) Q14 : gain of quantized pitch                    */
		Word16 mem[]                          /* (i/o)   : memory of gain of pitch clipping algorithm */
		)
{
	Word16 gain;
	Word32 L_tmp;
	L_tmp = (29491 * mem[1])<<1;
	L_tmp += (3277 * gain_pit)<<1;

	gain = extract_h(L_tmp);

	if(gain < GAIN_PIT_MIN)
	{
		gain = GAIN_PIT_MIN;              
	}
	mem[1] = gain;                         
	return;
}



