
//#ifdef HAVE_CONFIG_H
#include "config.h"
//#endif

#include "audio.h"
#include "ssc_generic.h"

#ifndef VC_PROJ
#include <xtensa/tie/xt_hifi2.h>
extern ae_int32 AE_MUL16S(ae_int16 b, ae_int16 c);
extern ae_int64 AE_MUL32_HH(ae_int32x2 d0, ae_int32x2 d1);
#endif
short win_square[108] = 
{
	0, 0, 0, 0, 1, 3, 6, 11, 18, 29, 43, 62, 86, 116, 155, 201, 257, 323, 402, 493, 598, 718, 855, 
	1010, 1182, 1375, 1589, 1823, 2081, 2362, 2667, 2997, 3353, 3733, 4140, 4572, 5031, 5514, 6025, 
	6559, 7117, 7699, 8304, 8929, 9574, 10239, 10920, 11617, 12326, 13048, 13779, 14517, 15261, 16009, 
	16758, 17506, 18249, 18988, 19719, 20441, 21150, 21847, 22528, 23193, 23838, 24463, 25068, 25649, 
	26207, 26743, 27252, 27737, 28195, 28627, 29034, 29414, 29769, 30100, 30406, 30686, 30944, 31179, 
	31392, 31584, 31757, 31911, 32049, 32168, 32273, 32365, 32444, 32510, 32566, 32612, 32650, 32682, 
	32706, 32724, 32738, 32750, 32756, 32762, 32764, 32766, 32766, 32766, 32766, 32766
};


#if 1

#ifdef FOR_VISUAL_C_NO_ASSM
static void comb_filter_const(int *y, short T, int N,
      short g10, short g11, short g12)
{
	int i;
//#if 0
#ifdef VC_PROJ
	long long Ltmp;
#else
	ae_int64 Ltmp;
#endif
	for (i=0; i<N; i++)
	{
//#if 0
#ifdef VC_PROJ
		Ltmp = SSC_MULT16x32(g10,y[i-T]) + SSC_MULT16x32(g11, SSC_ADD32(y[i-T+1],y[i-T-1])) + SSC_MULT16x32(g12, SSC_ADD32(y[i-T+2],y[i-T-2]));
#else
		Ltmp = SSC_MULT16x32(g10,y[i-T]);
		AE_MULA32_HH(Ltmp, g11,SSC_ADD32(y[i-T+1],y[i-T-1]));
		AE_MULA32_HH(Ltmp, g12,SSC_ADD32(y[i-T+2],y[i-T-2]));
#endif
		y[i] += (int)((long long)Ltmp>>15);
	}
}

#endif



void comb_filter(int *y,short T0, short T1, int N,
	short g0, short g1,int overlap)

{
//	int i;
	short g00, g01, g02, g10, g11, g12;
	short w2;
//#if 0
#ifdef VC_PROJ
	long long Ltmp;
#else
	ae_int64 Ltmp;
#endif

	short *win = win_square;
	int i;
	
	if (g0==0 && g1==0) return;
	if (g0==g1 && T0==T1) overlap=0;
	
	g00 = SSC_MULT16x16_Q15(g0, 10048);
	g01 = SSC_MULT16x16_Q15(g0, 7112);
	g02 = SSC_MULT16x16_Q15(g0, 4248);
	g10 = SSC_MULT16x16_Q15(g1, 10048);
	g11 = SSC_MULT16x16_Q15(g1, 7112);
	g12 = SSC_MULT16x16_Q15(g1, 4248);

	if(g0==0)
	{
		i = overlap;
		do
		{
			w2 = *win++;
//#if 0
#ifdef VC_PROJ
			Ltmp = SSC_MULT16x32(SSC_MULT16x16_Q15(w2,g10),y[-T1])
				+ SSC_MULT16x32(SSC_MULT16x16_Q15(w2,g11),SSC_ADD32(y[-T1+1],y[-T1-1]))
				+ SSC_MULT16x32(SSC_MULT16x16_Q15(w2,g12),SSC_ADD32(y[-T1+2],y[-T1-2]));
#else
			Ltmp = SSC_MULT16x32(SSC_MULT16x16_Q15(w2,g10),y[-T1]);
			AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15(w2,g11),SSC_ADD32(y[-T1+1],y[-T1-1]));
			AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15(w2,g12),SSC_ADD32(y[-T1+2],y[-T1-2]));
#endif
			*y += (int)((long long)Ltmp>>15);
			y++;
		}
		while(--i);

	}
	else if(g1==0)
	{
		i = overlap;
		do				
		{
			w2 = *win++;
//#if 0
#ifdef VC_PROJ
			Ltmp = SSC_MULT16x32(SSC_MULT16x16_Q15((Q15ONE-w2),g00),y[-T0])
				+ SSC_MULT16x32(SSC_MULT16x16_Q15((Q15ONE-w2),g01),SSC_ADD32(y[-T0+1],y[-T0-1]))
				+ SSC_MULT16x32(SSC_MULT16x16_Q15((Q15ONE-w2),g02),SSC_ADD32(y[-T0+2],y[-T0-2]));
#else
			Ltmp = SSC_MULT16x32(SSC_MULT16x16_Q15((Q15ONE-w2),g00),y[-T0]);
			AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15((Q15ONE-w2),g01),SSC_ADD32(y[-T0+1],y[-T0-1]));
			AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15((Q15ONE-w2),g02),SSC_ADD32(y[-T0+2],y[-T0-2]));
#endif
			*y += (int)((long long)Ltmp>>15);
			y++;
		}
		while(--i);

		return;
	}
	else
	{
		if(T0==T1)
		{
		
		for(i=0;i<overlap;i++)			
		{

				w2 = *win++;
//#if 0
#ifdef VC_PROJ
				Ltmp = SSC_MULT16x32((SSC_MULT16x16_Q15((Q15ONE-w2),g00)+SSC_MULT16x16_Q15(w2,g10)),y[-T0])
					+ SSC_MULT16x32((SSC_MULT16x16_Q15((Q15ONE-w2),g01)+SSC_MULT16x16_Q15(w2,g11)),SSC_ADD32(y[-T0+1],y[-T0-1]))
					+ SSC_MULT16x32((SSC_MULT16x16_Q15((Q15ONE-w2),g02)+SSC_MULT16x16_Q15(w2,g12)),SSC_ADD32(y[-T0+2],y[-T0-2]));
#else
				Ltmp = SSC_MULT16x32((SSC_MULT16x16_Q15((Q15ONE-w2),g00)+SSC_MULT16x16_Q15(w2,g10)),y[-T0]);
				AE_MULA32_HH(Ltmp, (SSC_MULT16x16_Q15((Q15ONE-w2),g01)+SSC_MULT16x16_Q15(w2,g11)),SSC_ADD32(y[-T0+1],y[-T0-1]));
				AE_MULA32_HH(Ltmp, (SSC_MULT16x16_Q15((Q15ONE-w2),g02)+SSC_MULT16x16_Q15(w2,g12)),SSC_ADD32(y[-T0+2],y[-T0-2]));
#endif
				*y += (int)((long long)Ltmp>>15);
				y++;				
			}

		}
		else
		{

	
		for(i=0;i<overlap;i++)			
			{

				w2 = *win++;
//#if 0
#ifdef VC_PROJ
						Ltmp = SSC_MULT16x32(SSC_MULT16x16_Q15((Q15ONE-w2),g00),y[-T0])
							+ SSC_MULT16x32(SSC_MULT16x16_Q15((Q15ONE-w2),g01),SSC_ADD32(y[-T0+1],y[-T0-1]))
							+ SSC_MULT16x32(SSC_MULT16x16_Q15((Q15ONE-w2),g02),SSC_ADD32(y[-T0+2],y[-T0-2]))
							+ SSC_MULT16x32(SSC_MULT16x16_Q15(w2,g10),y[-T1])
							+ SSC_MULT16x32(SSC_MULT16x16_Q15(w2,g11),SSC_ADD32(y[-T1+1],y[-T1-1]))
							+ SSC_MULT16x32(SSC_MULT16x16_Q15(w2,g12),SSC_ADD32(y[-T1+2],y[-T1-2]));
#else
						Ltmp = SSC_MULT16x32(SSC_MULT16x16_Q15((Q15ONE-w2),g00),y[-T0]);
						AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15((Q15ONE-w2),g01),SSC_ADD32(y[-T0+1],y[-T0-1]));
						AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15((Q15ONE-w2),g02),SSC_ADD32(y[-T0+2],y[-T0-2]));
						AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15(w2,g10),y[-T1]);
						AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15(w2,g11),SSC_ADD32(y[-T1+1],y[-T1-1]));
						AE_MULA32_HH(Ltmp, SSC_MULT16x16_Q15(w2,g12),SSC_ADD32(y[-T1+2],y[-T1-2]));
#endif
						*y += (int)((long long)Ltmp>>15);
						y++;
			}
		}
	}

#ifndef FOR_VISUAL_C_NO_ASSM
	if(N-overlap != 0)
		comb_filter_const_asm(y, T1, N-overlap, g10, g11, g12);
#else
	comb_filter_const(y, T1, N-overlap, g10, g11, g12);
#endif

}

const signed char tf_select_table[8] = {
	0, -2, 0, -3, 3, 0, 1,-1
};
#endif



