/*-------------------------------------------------------------------------*\

	FILE........: FFTSTAGE.C
	TYPE........: C Module
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	Fixed point development of the fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

#include "fftstage.h"

/*-------------------------------------------------------------------------*\

	FUNCTION....: fft_stage_1
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	First stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

void fft_stage_1(int *data, int nn)
/* int data[]		ptr to input data array				*/
/* int nn               number of points in the fft			*/
{
	long 	acc,          	/* 32 bit accumulators			*/
		bcc;
	int 	i;
	for(i=1;i<=nn;i+=2)
	{
	    acc = (long)data[i]<<15;
	    bcc = (long)data[i+1]<<15;
	    data[i] = (acc +bcc)>>16;
	    data[i+1] = (acc -bcc)>>16;
	}
}

/*-------------------------------------------------------------------------*\

	FUNCTION....: fft_stage_2
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	Second stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

void fft_stage_2(int *data, int nn)
/* int data[]		ptr to input data array				*/
/* int nn               number of points in the fft			*/
{
	long 	acc,          	/* 32 bit accumulators			*/
		bcc;
	int 	i;

	for(i=1;i<=nn;i+=4)
	{
	    acc = (long)data[i]<<15;
	    bcc = (long)data[i+2]<<15;
	    data[i] = (acc +bcc)>>16;
	    data[i+2] = (acc -bcc)>>16;
	    data[i+1] = data[i+1]>>1;
	    data[i+3] = -data[i+3]>>1;
	}
}

/*-------------------------------------------------------------------------*\

	FUNCTION....: zeroa
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	Part of third stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.
	First half of a butterfly.

\*-------------------------------------------------------------------------*/

void zeroa(int *data, int N2,int i)
/* int data[]		ptr to input data array				*/
/* int N2      		index for the butterfly				*/
/* int i		index of data array				*/
{
	long 	acc,          	/* 32 bit accumulators			*/
		bcc;

	/* zeroa - 1st half of butterfly */
	    acc = (long)data[i]<<15;
	    bcc = (long)data[i+N2]<<15;
	    data[i] = (acc +bcc)>>16;
	    data[i+N2] = (acc -bcc)>>16;
}

/*-------------------------------------------------------------------------*\

	FUNCTION....: zerob
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	Part of third stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.
	Last half of a butterfly.
\*-------------------------------------------------------------------------*/

void zerob(int *data, int N2, int N4,int i)
/* int data[]		ptr to input data array				*/
/* int N2,N4      	index for the butterfly				*/
/* int i		index of data array				*/
{
	long 	acc,          	/* 32 bit accumulators			*/
		bcc;

	/* zerob - other half of butterfly */

	acc = (long)data[i+N4]<<15;
	bcc = (long)data[i+N2+N4]<<15;
	data[i+N4] = (acc)>>16;
	data[i+N2+N4] = (-bcc)>>16;
}
/*-------------------------------------------------------------------------*\

	FUNCTION....: rlbutt45
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	Part of third stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.
	Butterfly with angle being 45 degrees.
\*-------------------------------------------------------------------------*/

void rlbutt45(int *data, int SS, int I1,int I2,int I3,int I4,int i)
/* int data[]		ptr to input data array				*/
/* int SS		sine(45) = cos(45)				*/
/* int I1,I2,I3,I4      indexes for the butterfly			*/
/* int i		index of data array				*/
{
	long 	acc,          	/* 32 bit accumulators			*/
		bcc;
	int	T1;
	long 	tempil;

	acc = (long)data[i+I3] * (long)SS;
	bcc = (long)data[i+I4] * (long)SS;
	T1 = (long)((acc + bcc) << 1) >>16;
	tempil = (bcc - acc);

	/*   data[I4] = (data[I2] - T2)/2 	*/

	acc = (long)data[i+I2]<<15;
	bcc = tempil;
	data[i+I4] = (long)(acc+bcc)>>16;

	/*   data[I3] = (-data[I2] - T2)/2     */

	acc = (long)data[i+I2]<<15;
	bcc = tempil;
	data[i+I3] = (long)(-acc+bcc)>>16;

	/* data[I2] = (data[I1] - T1)/2		*/

	acc = (long)data[i+I1]<<15;
	bcc = (long)T1<<15;
	data[i+I2] = (long)(acc-bcc)>>16;

	/* data[I1] = (data[I1] + T1)/2		*/

	acc = (long)data[i+I1]<<15;
	bcc = (long)T1<<15;
	data[i+I1] = (long)(acc+bcc)>>16;
}


/*-------------------------------------------------------------------------*\

	FUNCTION....: fft_stage_3
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	Third stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

void fft_stage_3(int *data, int nn)
/* int data[]		ptr to input data array				*/
/* int nn               number of points in the fft			*/
{
	int 	i;

	for(i=1;i<=nn;i+=8)
	{
	/* zeroa - 1st half of butterfly */

	    zeroa(data,4,i);

	/* zerob - other half of butterfly */

	    zerob(data,4,2,i);

	/* rlbutt45 */

	    rlbutt45(data,0x5a82,1,3,5,7,i);

	}
}
/*-------------------------------------------------------------------------*\

	FUNCTION....: fft_stage_4
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	Fourth stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

void fft_stage_4(int *data, int nn)
/* int data[]		ptr to input data array				*/
/* int nn               number of points in the fft			*/
{
	int 	i;

	for(i=1;i<=nn;i+=16)
	{
	/* zeroa - 1st half of butterfly */

	    zeroa(data,8,i);

	/* zerob - other half of butterfly */

	    zerob(data,8,4,i);

	/* rlbuttsp */

	    rlbuttsp(data,0x7642,0x30fc,1,7,9,15,i);

	/* rlbutt45 */

	    rlbutt45(data,0x5a82,2,6,10,14,i);

	/* rlbuttsp */

	    rlbuttsp(data,0x30fc,0x7642,3,5,11,13,i);

	}
}
/*-------------------------------------------------------------------------*\

	FUNCTION....: rlbuttsp
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 10/6/96

	Part of fourth stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.
	Special Butterfly.
\*-------------------------------------------------------------------------*/

void rlbuttsp(int *data, int CC,int SS, int I1,int I2,int I3,int I4,int i)
/* int data[]		ptr to input data array				*/
/* int CC		cosine(angle) 					*/
/* int SS		sine(angle) 					*/
/* int I1,I2,I3,I4      indexes for the butterfly			*/
/* int i		index of data array				*/
{
	long 	acc,          	/* 32 bit accumulators			*/
		bcc;
	int	T1;
	long 	tempil;

	acc = (long)data[i+I3] * (long)CC;
	bcc = (long)data[i+I4] * (long)SS;
	T1 = (long)((acc + bcc) << 1) >>16;

	acc = (long)data[i+I3] * (long)SS;
	bcc = (long)data[i+I4] * (long)CC;
	tempil = (bcc - acc);

	/*   data[I4] = (data[I2] - T2)/2 	*/

	acc = (long)data[i+I2]<<15;
	bcc = tempil;
	data[i+I4] = (long)(acc+bcc)>>16;

	/*   data[I3] = (-data[I2] - T2)/2     */

	acc = (long)data[i+I2]<<15;
	bcc = tempil;
	data[i+I3] = (long)(-acc+bcc)>>16;

	/* data[I2] = (data[I1] - T1)/2		*/

	acc = (long)data[i+I1]<<15;
	bcc = (long)T1<<15;
	data[i+I2] = (long)(acc-bcc)>>16;

	/* data[I1] = (data[I1] + T1)/2		*/

	acc = (long)data[i+I1]<<15;
	bcc = (long)T1<<15;
	data[i+I1] = (long)(acc+bcc)>>16;
}
/*-------------------------------------------------------------------------*\

	FUNCTION....: fft_stage_5
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 12/6/96

	Fifth stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

void fft_stage_5(int *data, int nn, int *cos)
/* int data[]		ptr to input data array				*/
/* int nn               number of points in the fft			*/
/* int *cos             ptr to cosine array				*/

{
	int 	i,j,l,s;

	for(i=1;i<=nn;i+=32)
	{

	/* zeroa - 1st half of butterfly */

	    zeroa(data,16,i);

	/* zerob - other half of butterfly */

	    zerob(data,16,8,i);


	l = nn/32;

	/* rlbutt16 */


	    for(j=0;j<7;j++)
	    {


	       s = j*l+l;
	       rlbutt16(data,cos[s],cos[64-s],1+j,15-j,17+j,31-j,i);
	    }

	}
}
/*-------------------------------------------------------------------------*\

	FUNCTION....: rlbutt16
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 12/6/96

	Part of subsequent stages of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.
\*-------------------------------------------------------------------------*/

void rlbutt16(int *data, int CC,int SS, int I1,int I2,int I3,int I4,int i)
/* int data[]		ptr to input data array				*/
/* int CC		cosine(angle) 					*/
/* int SS		sine(angle) 					*/
/* int I1,I2,I3,I4      indexes for the butterfly			*/
/* int i		index of data array				*/
{
	long 	acc,          	/* 32 bit accumulators			*/
		bcc;
	int	T1;
	long 	tempil;

	acc = (long)data[i+I3] * (long)CC;
	bcc = (long)data[i+I4] * (long)SS;
	T1 = (long)((acc + bcc) << 1) >>16;

	acc = (long)data[i+I3] * (long)SS;
	bcc = (long)data[i+I4] * (long)CC;
	tempil = (bcc - acc);

	/*   data[I4] = (data[I2] - T2)/2 	*/

	acc = (long)data[i+I2]<<15;
	bcc = tempil;
	data[i+I4] = (long)(acc+bcc)>>16;

	/*   data[I3] = (-data[I2] - T2)/2     */

	acc = (long)data[i+I2]<<15;
	bcc = tempil;
	data[i+I3] = (long)(-acc+bcc)>>16;

	/* data[I2] = (data[I1] - T1)/2		*/

	acc = (long)data[i+I1]<<15;
	bcc = (long)T1<<15;
	data[i+I2] = (long)(acc-bcc)>>16;

	/* data[I1] = (data[I1] + T1)/2		*/

	acc = (long)data[i+I1]<<15;
	bcc = (long)T1<<15;
	data[i+I1] = (long)(acc+bcc)>>16;
}

/*-------------------------------------------------------------------------*\

	FUNCTION....: fft_stage_6
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 12/6/96

	Sixth stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

void fft_stage_6(int *data, int nn, int *cos)
/* int data[]		ptr to input data array				*/
/* int nn               number of points in the fft			*/
/* int *cos             ptr to cosine array				*/

{
	int 	i,j,l,s;

	for(i=1;i<=nn;i+=64)
	{

	/* zeroa - 1st half of butterfly */

	    zeroa(data,32,i);

	/* zerob - other half of butterfly */

	    zerob(data,32,16,i);

	l = nn/64;

	/* rlbutt16 */

	    for(j=0;j<15;j++)
	    {
	       s = j*l+l;
	       rlbutt16(data,cos[s],cos[64-s],1+j,31-j,33+j,63-j,i);
	    }
	}
}

/*-------------------------------------------------------------------------*\

	FUNCTION....: fft_stage_7
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 14/6/96

	Seventh stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

void fft_stage_7(int *data, int nn, int *cos)
/* int data[]		ptr to input data array				*/
/* int nn               number of points in the fft			*/
/* int *cos             ptr to cosine array				*/

{
	int 	i,j,l,s;

	for(i=1;i<=nn;i+=128)
	{

	/* zeroa - 1st half of butterfly */

	    zeroa(data,64,i);

	/* zerob - other half of butterfly */

	    zerob(data,64,32,i);

	l = nn/128;

	/* rlbutt16 */

	    for(j=0;j<31;j++)
	    {
	       s = j*l+l;
	       rlbutt16(data,cos[s],cos[64-s],1+j,63-j,65+j,127-j,i);
	    }
	}
}

/*-------------------------------------------------------------------------*\

	FUNCTION....: fft_stage_8
	COMPANY.....: VoiceTronix
	AUTHOR......: John Kostogiannis
	DATE CREATED: 14/6/96

	Eighth stage of the Fixed point fft routine compatible with the
	C5x code by Papamichalis.

\*-------------------------------------------------------------------------*/

void fft_stage_8(int *data, int nn, int *cos)
/* int data[]		ptr to input data array				*/
/* int nn               number of points in the fft			*/
/* int *cos             ptr to cosine array				*/

{
	int 	i,j,l,s;

	for(i=1;i<=nn;i+=256)
	{

	/* zeroa - 1st half of butterfly */

	    zeroa(data,128,i);

	/* zerob - other half of butterfly */

	    zerob(data,128,64,i);

	l = nn/256;

	/* rlbutt16 */

	    for(j=0;j<63;j++)
	    {
	       s = j*l+l;
	       rlbutt16(data,cos[s],cos[64-s],1+j,127-j,129+j,255-j,i);
	    }
	}
}

