#include "config.h"
#include "ssc_imdct.h"
#include "ssc_ifft.h"
#include "ssc_guts.h"

#ifndef VC_PROJ
#include <xtensa/tie/xt_hifi2.h>
extern ae_int64 AE_MUL32_HH(ae_int32x2 d0, ae_int32x2 d1);
extern void AE_MULA32_HH(ae_int64 d /*inout*/, ae_int32x2 d0, ae_int32x2 d1);
extern void AE_MULS32_HH(ae_int64 d /*inout*/, ae_int32x2 d0, ae_int32x2 d1);
extern void AE_MULA32X2_vector(ae_int64x2 d /*inout*/, ae_int32x2 d0, ae_int32x2 d1);
#endif



#ifndef KALI_DEBUGGING
extern short SSC_shared_mem[1728];
#else
extern short SSC_shared_mem[1728+4];
#endif
//extern short SSC_shared_mem[1872];


#ifndef MDCT_23BIT_TABLE
static const short mdct_twiddles[433] = {
	32767, 32767, 32767, 32766, 32765, 32763, 32760, 32757, 32754, 32750, 32746, 32742, 32737, 32731, 32726, 32719, 
	32713, 32705, 32698, 32690, 32681, 32673, 32663, 32653, 32643, 32633, 32622, 32610, 32598, 32586, 32573, 32560, 
	32546, 32532, 32518, 32503, 32488, 32472, 32456, 32439, 32422, 32405, 32387, 32368, 32350, 32330, 32311, 32291, 
	32270, 32249, 32228, 32206, 32184, 32161, 32138, 32115, 32091, 32067, 32042, 32017, 31991, 31965, 31939, 31912, 
	31885, 31857, 31829, 31800, 31771, 31742, 31712, 31682, 31651, 31620, 31589, 31557, 31525, 31492, 31459, 31425, 
	31391, 31357, 31322, 31287, 31251, 31215, 31179, 31142, 31105, 31067, 31029, 30991, 30952, 30912, 30873, 30832, 
	30792, 30751, 30710, 30668, 30626, 30583, 30540, 30497, 30453, 30409, 30364, 30319, 30274, 30228, 30182, 30135, 
	30088, 30041, 29993, 29945, 29896, 29847, 29798, 29748, 29698, 29647, 29596, 29545, 29493, 29441, 29389, 29336, 
	29283, 29229, 29175, 29120, 29066, 29010, 28955, 28899, 28842, 28786, 28729, 28671, 28613, 28555, 28496, 28437, 
	28378, 28318, 28258, 28198, 28137, 28075, 28014, 27952, 27889, 27827, 27764, 27700, 27636, 27572, 27507, 27443, 
	27377, 27312, 27246, 27179, 27112, 27045, 26978, 26910, 26842, 26773, 26705, 26635, 26566, 26496, 26426, 26355, 
	26284, 26213, 26141, 26069, 25997, 25924, 25851, 25777, 25704, 25630, 25555, 25481, 25405, 25330, 25254, 25178, 
	25102, 25025, 24948, 24870, 24793, 24715, 24636, 24558, 24479, 24399, 24319, 24239, 24159, 24078, 23997, 23916, 
	23835, 23753, 23670, 23588, 23505, 23422, 23338, 23255, 23170, 23086, 23001, 22916, 22831, 22745, 22659, 22573, 
	22487, 22400, 22313, 22225, 22138, 22050, 21961, 21873, 21784, 21695, 21605, 21516, 21426, 21335, 21245, 21154, 
	21063, 20971, 20880, 20788, 20696, 20603, 20510, 20417, 20324, 20230, 20136, 20042, 19948, 19853, 19758, 19663, 
	19568, 19472, 19376, 19280, 19183, 19087, 18990, 18892, 18795, 18697, 18599, 18501, 18403, 18304, 18205, 18106, 
	18006, 17907, 17807, 17707, 17606, 17506, 17405, 17304, 17202, 17101, 16999, 16897, 16795, 16693, 16590, 16487, 
	16384, 16281, 16177, 16073, 15970, 15865, 15761, 15656, 15552, 15447, 15342, 15236, 15131, 15025, 14919, 14813, 
	14706, 14600, 14493, 14386, 14279, 14171, 14064, 13956, 13848, 13740, 13632, 13524, 13415, 13306, 13197, 13088, 
	12979, 12869, 12760, 12650, 12540, 12430, 12319, 12209, 12098, 11987, 11876, 11765, 11654, 11543, 11431, 11319, 
	11207, 11095, 10983, 10871, 10758, 10646, 10533, 10420, 10307, 10194, 10081, 9967, 9854, 9740, 9626, 9512, 9398, 
	9284, 9169, 9055, 8940, 8826, 8711, 8596, 8481, 8366, 8251, 8135, 8020, 7904, 7788, 7673, 7557, 7441, 7325, 7209, 
	7092, 6976, 6859, 6743, 6626, 6510, 6393, 6276, 6159, 6042, 5925, 5807, 5690, 5573, 5455, 5338, 5220, 5103, 4985, 
	4867, 4749, 4631, 4513, 4395, 4277, 4159, 4041, 3922, 3804, 3686, 3567, 3449, 3330, 3212, 3093, 2975, 2856, 2737, 
	2618, 2500, 2381, 2262, 2143, 2024, 1905, 1786, 1667, 1548, 1429, 1310, 1191, 1072, 953, 834, 715, 596, 477, 357, 
	238, 119, 0,
};
#else
static const int mdct_twiddles[433] = {
	4194303,4194276,4194193,4194054,4193860,4193611,4193306,4192945,4192530,4192058,4191532,4190949,4190312,4189619,
	4188871,4188067,4187208,4186293,4185324,4184299,4183218,4182082,4180891,4179645,4178343,4176987,4175575,4174107,
	4172585,4171007,4169374,4167687,4165944,4164146,4162292,4160384,4158421,4156403,4154330,4152202,4150019,4147781,
	4145489,4143141,4140739,4138282,4135770,4133204,4130583,4127908,4125177,4122393,4119553,4116660,4113712,4110709,
	4107652,4104541,4101376,4098156,4094882,4091554,4088172,4084736,4081246,4077702,4074104,4070452,4066746,4062987,
	4059174,4055307,4051387,4047413,4043385,4039304,4035170,4030982,4026741,4022447,4018099,4013699,4009245,4004738,
	4000179,3995566,3990901,3986183,3981412,3976589,3971713,3966784,3961803,3956770,3951684,3946547,3941357,3936114,
	3930820,3925474,3920076,3914626,3909124,3903571,3897966,3892310,3886602,3880842,3875032,3869170,3863257,3857293,
	3851277,3845211,3839095,3832927,3826709,3820440,3814120,3807751,3801330,3794860,3788339,3781769,3775148,3768477,
	3761757,3754987,3748167,3741298,3734379,3727411,3720393,3713326,3706211,3699046,3691832,3684570,3677259,3669899,
	3662490,3655034,3647529,3639975,3632374,3624724,3617027,3609282,3601489,3593648,3585760,3577825,3569842,3561812,
	3553735,3545611,3537440,3529222,3520958,3512647,3504290,3495886,3487436,3478940,3470398,3461810,3453177,3444498,
	3435773,3427002,3418187,3409326,3400420,3391469,3382474,3373433,3364349,3355219,3346045,3336827,3327565,3318259,
	3308909,3299515,3290078,3280597,3271073,3261505,3251894,3242241,3232544,3222805,3213023,3203199,3193332,3183423,
	3173472,3163479,3153445,3143368,3133250,3123091,3112890,3102648,3092365,3082041,3071677,3061272,3050826,3040340,
	3029814,3019248,3008642,2997996,2987310,2976585,2965821,2955017,2944175,2933293,2922373,2911413,2900416,2889380,
	2878306,2867194,2856044,2844856,2833631,2822368,2811068,2799730,2788356,2776945,2765497,2754012,2742491,2730934,
	2719341,2707712,2696047,2684346,2672610,2660838,2649032,2637190,2625313,2613402,2601456,2589476,2577462,2565413,
	2553330,2541214,2529064,2516881,2504665,2492415,2480132,2467817,2455469,2443089,2430676,2418231,2405754,2393245,
	2380705,2368133,2355530,2342896,2330230,2317534,2304808,2292051,2279263,2266445,2253598,2240721,2227814,2214877,
	2201911,2188917,2175893,2162840,2149759,2136649,2123512,2110346,2097152,2083930,2070681,2057405,2044101,2030771,
	2017413,2004029,1990618,1977181,1963718,1950229,1936714,1923174,1909608,1896016,1882400,1868759,1855093,1841403,
	1827688,1813949,1800186,1786400,1772589,1758756,1744899,1731019,1717116,1703190,1689242,1675272,1661279,1647264,
	1633228,1619170,1605091,1590990,1576868,1562726,1548563,1534379,1520175,1505951,1491707,1477444,1463161,1448858,
	1434536,1420196,1405836,1391458,1377062,1362647,1348215,1333764,1319296,1304811,1290308,1275788,1261252,1246698,
	1232128,1217542,1202940,1188322,1173688,1159039,1144374,1129694,1114999,1100290,1085566,1070827,1056075,1041308,
	1026528,1011734,996927 ,982106 ,967273 ,952427 ,937568 ,922697 ,907814 ,892918 ,878011 ,863092 ,848162 ,833221 ,
	818268 ,803305 ,788331 ,773347 ,758352 ,743348 ,728333 ,713309 ,698276 ,683233 ,668181 ,653121 ,638052 ,622974 ,
	607888 ,592794 ,577693 ,562583 ,547467 ,532342 ,517211 ,502074 ,486929 ,471778 ,456621 ,441458 ,426288 ,411114 ,
	395934 ,380748 ,365558 ,350362 ,335163 ,319958 ,304750 ,289537 ,274321 ,259101 ,243877 ,228650 ,213421 ,198188 ,
	182953 ,167715 ,152476 ,137234 ,121990 ,106745 ,91498  ,76250  ,61002  ,45752  ,30502  ,15251  ,0      ,
};
#endif




#ifndef WQ_OPTI3

void clt_mdct_backward(const kiss_fft_state *kfft, int *in, int * out,
					const short * window, int overlap, int shift, int stride)
{
	int i;
	int N, N2, N4;
	short sine;
	int *f2;
//#if 0
#ifdef VC_PROJ
	long long tmp_val;
#else
	ae_int64 tmp_val;
#endif
	int yr,yi;

#ifndef MDCT_23BIT_TABLE
	const short *t = mdct_twiddles;
		short t0,t1,t2;
#else
	const int *t = mdct_twiddles;
	int t0,t1,t2;
#endif
	


	N = 1728;
	N >>= shift;
	N2 = N>>1;
	N4 = N>>2;
	

	f2 = (int *)SSC_shared_mem;



	/* Pre-rotate */
	{
		/* Temp pointers to make it really clear to the compiler what we're doing */
		const int * xp1 = in;
#if 0
		const int * xp2 = in+stride*(N2-1);
#else
		const int * xp2 = in+SSC_MULT16x16(stride, N2-1);
#endif
		int * yp = f2;


#ifndef MDCT_23BIT_TABLE
		const short * pt1 = &t[N4<<shift];
		const short * pt2 = &t[0];
#else
		const int * pt1 = &t[N4<<shift];
		const int * pt2 = &t[0];
#endif

		if(!shift)
		{
			sine = 3813; 
			for(i=N4;i!=0;i--) 
			{
//#if 0	//modify yang
#ifdef VC_PROJ
				t1 = *pt1--;
				t2 = *pt2++;
				tmp_val = ((long long)(*xp1))*t1;
				tmp_val = tmp_val - ((long long)(*xp2))*t2;
#ifndef MDCT_23BIT_TABLE
				yr = (int)(tmp_val>>15);
#else
				yr = (int)(tmp_val>>22);
#endif
				tmp_val = ((long long)(*xp2))*t1;
				tmp_val = tmp_val + ((long long)(*xp1))*t2;
#ifndef MDCT_23BIT_TABLE
				yi = (int)(tmp_val>>15);
#else
				yi = (int)(tmp_val>>22);
#endif
				yi = -yi;

				/* works because the cos is nearly one */
				tmp_val = ((long long)(yi)*(sine));
				*yp++ = yr - ((int)(tmp_val>>23));
				tmp_val = ((long long)(yr)*(sine));
				*yp++ = yi + ((int)(tmp_val>>23));
				xp1+=2;
				xp2-=2;
#else
				t1 = *pt1--;
				t2 = *pt2++;
				tmp_val = AE_MUL32_HH(*xp1, t1);
				AE_MULS32_HH(tmp_val, *xp2, t2);
#ifndef MDCT_23BIT_TABLE
				yr = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yr = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				tmp_val = AE_MUL32_HH(*xp2, t1);
				AE_MULA32_HH(tmp_val, *xp1, t2);
#ifndef MDCT_23BIT_TABLE
				yi = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yi = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				yi = -yi;

				/* works because the cos is nearly one */
				tmp_val = AE_MUL32_HH(yi, sine);
				*yp++ = yr - ((int)((long long)AE_SRAI64(tmp_val, 23)));

				tmp_val = AE_MUL32_HH(yr, sine);
				*yp++ = yi + ((int)((long long)AE_SRAI64(tmp_val, 23)));
				xp1+=2;
				xp2-=2;
#endif
			}
		}
		else
		{
			sine = 30502;
			for(i=N4;i!=0;i--)
			{
//#if 0	//modify yang
#ifdef VC_PROJ
				t1 = *pt1;
				t2 = *pt2;
				pt1 -= 8;
				pt2 += 8;
				tmp_val = ((long long)(*xp1))*t1;
				tmp_val = tmp_val - ((long long)(*xp2))*t2;
#ifndef MDCT_23BIT_TABLE
				yr = (int)(tmp_val>>15);
#else
				yr = (int)(tmp_val>>22);
#endif
				tmp_val = ((long long)(*xp2))*t1;
				tmp_val = tmp_val + ((long long)(*xp1))*t2;

#ifndef MDCT_23BIT_TABLE
				yi = (int)(tmp_val>>15);
#else
				yi = (int)(tmp_val>>22);
#endif
				yi = -yi;
				/* works because the cos is nearly one */
				tmp_val = ((long long)(yi)*(sine));
				*yp++ = yr - ((int)(tmp_val>>23));
				tmp_val = ((long long)(yr)*(sine));
				*yp++ = yi + ((int)(tmp_val>>23));
				xp1+=16;
				xp2-=16;
#else
				t1 = *pt1;
				t2 = *pt2;
				pt1 -= 8;
				pt2 += 8;
				tmp_val = AE_MUL32_HH(*xp1, t1);
				AE_MULS32_HH(tmp_val, *xp2, t2);
#ifndef MDCT_23BIT_TABLE
				yr = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yr = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				tmp_val = AE_MUL32_HH(*xp2, t1);
				AE_MULA32_HH(tmp_val, *xp1, t2);

#ifndef MDCT_23BIT_TABLE
				yi = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yi = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				yi = -yi;

				/* works because the cos is nearly one */
				tmp_val = AE_MUL32_HH(yi, sine);
				*yp++ = yr - ((int)((long long)AE_SRAI64(tmp_val, 23)));

				tmp_val = AE_MUL32_HH(yr, sine);
				*yp++ = yi + ((int)((long long)AE_SRAI64(tmp_val, 23)));

				xp1+=16;
				xp2-=16;
#endif
			}
		}
	}

	/* Inverse N/4 complex FFT. This one should *not* downscale even in fixed-point */
	ssc_ifft(kfft, f2, (out+(overlap>>1)));
	/* Post-rotate and de-shuffle from both ends of the buffer at once to make
		it in-place. */
   {
		int * yp0 = out+(overlap>>1);
		int * yp1 = out+(overlap>>1)+N2-2;

#ifndef MDCT_23BIT_TABLE
		short *p_t0 = (short *)t;
		short *p_t1 = (short *)&t[N4<<shift];
#else
		int *p_t0 = (int *)t;
		int *p_t1 = (int *)&t[N4<<shift];
#endif
		
		t0 = *p_t0;
		t1 = *p_t1;
		i=(N4+1)>>1;
      
		if(!shift)
		{ 
			do{
				int re, im; //, yr, yi;
				re = yp0[0];
				im = yp0[1];
//#if 0	//modify yang
#ifdef VC_PROJ
				/* We'd scale up by 2 here, but instead it's done when mixing the windows */
				tmp_val = (((long long)(re))*(t0));
				tmp_val = tmp_val - (((long long)(im))*(t1));
#ifndef MDCT_23BIT_TABLE
				yr = (int)(tmp_val>>15);
#else
				yr = (int)(tmp_val>>22);
#endif
				tmp_val = ((long long)(im))*(t0);
				tmp_val = tmp_val + (((long long)(re))*(t1));
#ifndef MDCT_23BIT_TABLE
				yi = (int)(tmp_val>>15);
#else
				yi = (int)(tmp_val>>22);
#endif

				re = yp1[0];
				im = yp1[1];
#else
				tmp_val = AE_MUL32_HH(re, t0);
				AE_MULS32_HH(tmp_val, im, t1);
#ifndef MDCT_23BIT_TABLE
				yr = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yr = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				tmp_val = AE_MUL32_HH(im, t0);
				AE_MULA32_HH(tmp_val, re, t1);
#ifndef MDCT_23BIT_TABLE
				yi = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yi = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				re = yp1[0];
				im = yp1[1];
#endif

//#if 0	//modify yang
#ifdef VC_PROJ
				/* works because the cos is nearly one */
				tmp_val = ((long long)(yi)*(sine));
				yp0[0] = -(yr - ((int)(tmp_val>>23)));

				tmp_val = ((long long)(yr)*(sine));
				yp1[1] = yi + ((int)(tmp_val>>23));
				t1 = *++p_t0;         
				t0 = *--p_t1;

#else
				tmp_val = AE_MUL32_HH(yi, sine);
				yp0[0] = -(yr - ((int)((long long)AE_SRAI64(tmp_val, 23))));

				tmp_val = AE_MUL32_HH(yr, sine);
				yp1[1] = yi + ((int)((long long)AE_SRAI64(tmp_val, 23)));

				t1 = *++p_t0;
				t0 = *--p_t1;
#endif

//#if 0	//modify yang
#ifdef VC_PROJ
				/* We'd scale up by 2 here, but instead it's done when mixing the windows */
				tmp_val = (((long long)(re))*(t0));
				tmp_val = tmp_val - (((long long)(im))*(t1));
#ifndef MDCT_23BIT_TABLE
				yr = (int)(tmp_val>>15);
#else
				yr = (int)(tmp_val>>22);
#endif
				tmp_val = ((long long)(im))*(t0);
				tmp_val = tmp_val + (((long long)(re))*(t1));
#ifndef MDCT_23BIT_TABLE
				yi = (int)(tmp_val>>15);
#else
				yi = (int)(tmp_val>>22);
#endif
				t1 = *p_t1;
				t0 = *p_t0;
#else
				tmp_val = AE_MUL32_HH(re, t0);
				AE_MULS32_HH(tmp_val, im, t1);
#ifndef MDCT_23BIT_TABLE
				yr = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yr = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				tmp_val = AE_MUL32_HH(im, t0);
				AE_MULA32_HH(tmp_val, re, t1);
#ifndef MDCT_23BIT_TABLE
				yi = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yi = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				t1 = *p_t1;
				t0 = *p_t0;
#endif

//#if 0	//modify yang
#ifdef VC_PROJ
				/* works because the cos is nearly one */
				tmp_val = ((long long)(yi)*(sine));
				yp1[0] = -(yr - ((int)(tmp_val>>23)));
				tmp_val = ((long long)(yr)*(sine));
				yp0[1] = yi + ((int)(tmp_val>>23));
				yp0 += 2;
				yp1 -= 2;
#else
				tmp_val = AE_MUL32_HH(yi, sine);
				yp1[0] = -(yr - ((int)((long long)AE_SRAI64(tmp_val, 23))));

				tmp_val = AE_MUL32_HH(yr, sine);
				yp0[1] = yi + ((int)((long long)AE_SRAI64(tmp_val, 23)));

				yp0 += 2;
				yp1 -= 2;
#endif
			}while(--i);
		}
		else
		{
			do{
				int re, im;
//#if 0	//modify yang
#ifdef VC_PROJ
				re = yp0[0];
				im = yp0[1];
				/* We'd scale up by 2 here, but instead it's done when mixing the windows */
				tmp_val = (((long long)(re))*(t0));
				tmp_val = tmp_val - (((long long)(im))*(t1));
#ifndef MDCT_23BIT_TABLE
				yr = (int)(tmp_val>>15);
#else
				yr = (int)(tmp_val>>22);
#endif
				tmp_val = ((long long)(im))*(t0);
				tmp_val = tmp_val + (((long long)(re))*(t1));
#ifndef MDCT_23BIT_TABLE
				yi = (int)(tmp_val>>15);
#else
				yi = (int)(tmp_val>>22);
#endif
#else
				re = yp0[0];
				im = yp0[1];
				/* We'd scale up by 2 here, but instead it's done when mixing the windows */
				tmp_val = AE_MUL32_HH(re, t0);
				AE_MULS32_HH(tmp_val, im, t1);
#ifndef MDCT_23BIT_TABLE
				yr = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yr = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif

				tmp_val = AE_MUL32_HH(im, t0);
				AE_MULA32_HH(tmp_val, re, t1);

#ifndef MDCT_23BIT_TABLE
				yi = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yi = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif

#endif

//#if 0	//modify yang
#ifdef VC_PROJ
				re = yp1[0];
				im = yp1[1];
				/* works because the cos is nearly one */
				tmp_val = ((long long)(yi)*(sine));
				yp0[0] = -(yr - ((int)(tmp_val>>23)));
				tmp_val = ((long long)(yr)*(sine));
				yp1[1] = yi + ((int)(tmp_val>>23));
				p_t0 = p_t0+8;
				t1 = *p_t0;
				p_t1 = p_t1-8;         
				t0 = *p_t1;
#else
				re = yp1[0];
				im = yp1[1];
				/* works because the cos is nearly one */
				tmp_val = AE_MUL32_HH(yi, sine);
				yp0[0] = -(yr - ((int)((long long)AE_SRAI64(tmp_val, 23))));

				tmp_val = AE_MUL32_HH(yr, sine);
				yp1[1] = yi + ((int)((long long)AE_SRAI64(tmp_val, 23)));

				p_t0 = p_t0+8;
				t1 = *p_t0;
				p_t1 = p_t1-8;
				t0 = *p_t1;
#endif

//#if 0	//modify yang
#ifdef VC_PROJ
				/* We'd scale up by 2 here, but instead it's done when mixing the windows */
				tmp_val = (((long long)(re))*(t0));
				tmp_val = tmp_val - (((long long)(im))*(t1));
#ifndef MDCT_23BIT_TABLE
				yr = (int)(tmp_val>>15);
#else
				yr = (int)(tmp_val>>22);
#endif
				tmp_val = ((long long)(im))*(t0);
				tmp_val = tmp_val + (((long long)(re))*(t1));
#ifndef MDCT_23BIT_TABLE
				yi = (int)(tmp_val>>15);
#else
				yi = (int)(tmp_val>>22);
#endif
				t1 = *p_t1;
				t0 = *p_t0;
				/* works because the cos is nearly one */
				tmp_val = ((long long)(yi)*(sine));
				yp1[0] = -(yr - ((int)(tmp_val>>23)));
				tmp_val = ((long long)(yr)*(sine));
				yp0[1] = yi + ((int)(tmp_val>>23));
				yp0 += 2;
				yp1 -= 2;
#else
				/* We'd scale up by 2 here, but instead it's done when mixing the windows */
				tmp_val = AE_MUL32_HH(re, t0);
				AE_MULS32_HH(tmp_val, im, t1);
#ifndef MDCT_23BIT_TABLE
				yr = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yr = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif

				tmp_val = AE_MUL32_HH(im, t0);
				AE_MULA32_HH(tmp_val, re, t1);
#ifndef MDCT_23BIT_TABLE
				yi = (int)((long long)AE_SRAI64(tmp_val, 15));
#else
				yi = (int)((long long)AE_SRAI64(tmp_val, 22));
#endif
				t1 = *p_t1;
				t0 = *p_t0;

				/* works because the cos is nearly one */
				tmp_val = AE_MUL32_HH(yi, sine);
				yp1[0] = -(yr - ((int)((long long)AE_SRAI64(tmp_val, 23))));

				tmp_val = AE_MUL32_HH(yr, sine);
				yp0[1] = yi + ((int)((long long)AE_SRAI64(tmp_val, 23)));

				yp0 += 2;
				yp1 -= 2;
#endif
			}while(--i);
		}
	}

	/* Mirror on both sides for TDAC */
	{
		int * xp1 = out+overlap-1;
		int * yp1 = out;
		const short * wp1 = window;
		const short * wp2 = window+overlap-1;

		i = (overlap>>1);
		do{
			int x1, x2;
			x1 = *xp1;
			x2 = *yp1;
//#if 0	//modify yang
#ifdef VC_PROJ
			tmp_val = (((long long)(x2))*(*wp2));
			tmp_val = tmp_val - (((long long)(x1))*(*wp1));
			*yp1++ = (int)(tmp_val>>15);

			tmp_val = ((long long)(x2))*(*wp1);
			tmp_val = tmp_val + (((long long)(x1))*(*wp2));
			*xp1-- = (int)(tmp_val>>15);
#else
			tmp_val = AE_MUL32_HH(x2, *wp2);
			AE_MULS32_HH(tmp_val, x1, *wp1);
			*yp1++ = (int)((long long)AE_SRAI64(tmp_val, 15));

			tmp_val = AE_MUL32_HH(x2, *wp1);
			AE_MULA32_HH(tmp_val, x1, *wp2);
			*xp1-- = (int)((long long)AE_SRAI64(tmp_val, 15));
#endif
			wp1++;
			wp2--;
		}while(--i);
	}
}
#else



#define OFFSET0 0
#define OFFSET1 110

#if 0
void clt_mdct_backward_prerotate(const int *xp1, const int *xp2, int *yp, const short *t, int step, int N)
{
	int i;
	const short *pt0, *pt1;
	short t0,t1;
	long long tmp_val;
	pt0 = &t[1];
	pt1 = &t[N];
	for(i=(N>>1);i!=0;i--)
	{
		t1 = *pt1; pt1 -= 2;
		t0 = *pt0; pt0 += 2;
		tmp_val = ((long long)(*xp1))*t1;
		tmp_val = tmp_val - ((long long)(*xp2))*t0;
		*yp++ = (int)(tmp_val>>15);
		tmp_val = -((long long)(*xp2))*t1;
		tmp_val = tmp_val - ((long long)(*xp1))*t0;
		*yp++ = (int)(tmp_val>>15);
		xp1+=step;
		xp2-=step;
	}
}

void clt_mdct_backward_postrotate(int *yp0, int *yp1, const short *t, int N)
{
	int i;
	const short *pt0, *pt1;
	short t0,t1;
	int yr,yi;
	long long tmp_val;
	
	i = N>>2;
	pt0 = &t[1];
	pt1 = &t[N];
	t0 = *pt0; pt0 += 2;
	t1 = *pt1; pt1 -= 2;
	do
	{
		int re, im; //, yr, yi;
		re = yp0[0];
		im = yp0[1];
		/* We'd scale up by 2 here, but instead it's done when mixing the windows */
		tmp_val = -(((long long)(re))*(t0));
		tmp_val = tmp_val + (((long long)(im))*(t1));
		yr = (int)(tmp_val>>15);
		tmp_val = ((long long)(im))*(t0);
		tmp_val = tmp_val + (((long long)(re))*(t1));
		yi = (int)(tmp_val>>15);
		re = yp1[0];
		im = yp1[1];
		yp0[0] = yr;
		yp1[1] = yi;
		t1 = pt0[-1]; 
		t0 = pt1[1];
		/* We'd scale up by 2 here, but instead it's done when mixing the windows */
		tmp_val = -(((long long)(re))*(t0));
		tmp_val = tmp_val + (((long long)(im))*(t1));
		yr = (int)(tmp_val>>15);
		tmp_val = ((long long)(im))*(t0);
		tmp_val = tmp_val + (((long long)(re))*(t1));
		yi = (int)(tmp_val>>15);
		t0 = *pt0; pt0 += 2;
		t1 = *pt1; pt1 -= 2;
		yp1[0] = yr;
		yp0[1] = yi;
		yp0 += 2;
		yp1 -= 2;
	}while(--i);
}

void clt_mdct_backward_tdac(int *yp1, const short *wp1, int overlap)
{
	int *xp1;
	const short *wp2;
	int i, x1, x2;
	long long tmp_val;
	
	xp1 = yp1 + overlap - 1;
	wp2 = wp1 + overlap - 1;
	i = (overlap>>1);
	do{
		x1 = *xp1;
		x2 = *yp1;
		tmp_val = (((long long)(x2))*(*wp2));
		tmp_val = tmp_val - (((long long)(x1))*(*wp1));
		*yp1++ = (int)(tmp_val>>15);
		tmp_val = ((long long)(x2))*(*wp1);
		tmp_val = tmp_val + (((long long)(x1))*(*wp2));
		*xp1-- = (int)(tmp_val>>15);
		wp1++;
		wp2--;
	}while(--i);
}

#endif


void clt_mdct_backward(const mdct_lookup *l, int *in, int * SSC_RESTRICT out,
      const short * SSC_RESTRICT window, int overlap, int shift, int stride)
{
	int step, N;
	int *f2;
	const short *t;

	N = 1728;
	N >>= (shift+1);

	if(shift)
	{
		f2 = (int *)SSC_shared_mem;
		t = &l->trig[OFFSET0];
		step = 16;
	}
	else
	{
		f2 = (int *)shared_local;
		t = &l->trig[OFFSET1];
		step = 2;
	}

	/* Pre-rotate */
	clt_mdct_backward_prerotate_asm(in, in+stride*(N-1), f2, t, step, N);

	/* Inverse N/4 complex FFT. This one should *not* downscale even in fixed-point */
	ssc_ifft(l->kfft[shift>>1], f2, (out+(overlap>>1)));

	/* Post-rotate and de-shuffle from both ends of the buffer at once to make
		it in-place. */
	clt_mdct_backward_postrotate_asm(out+(overlap>>1), out+(overlap>>1)+N-2, t, N);
	
	/* Mirror on both sides for TDAC */
	clt_mdct_backward_tdac_asm(out, window, overlap);
}

#endif
