// fixed point implemention of dft and IDFT
#include <stdio.h>
#include <math.h>
#include "input32_DFT_IDFT_float.h"
#include "input32_DFT_IDFT_fixed.h"
#define N 32
#define PI (float)3.1416
#define Q15 (unsigned int)32768
#define Q14 (unsigned int)(Q15>>1)
#define Q8 (unsigned int)256
typedef struct {
float real[N];
float imag[N];
}complex;
complex xn,Xk,xc;
//Declare Structure for storing fixed point numbers
typedef struct {
int real[N];
int imag[N];
}complex_fix;
complex_fix xnn,Xkk,xcc;
float chk_real_fix_dft[N];
float chk_imag_fix_dft[N];
float chk_real_fix_idft[N];
float chk_imag_fix_idft[N];
//declare function prototype for DFT and IDFT Calculation
void dft_fix(complex_fix *g,complex_fix *G,int len);
void idft_fix(complex_fix *g,complex_fix *G,int len);
void main()
{int n;
//input values for DFT Calculation
for(n=0;n<N;n++)
{
xn.real[n] = x[n];
xn.imag[n] = 0;
}
//input values for DFT Calculation using Fixed point Technique
for(n=0;n<N;n++)
{
xnn.real[n] = x_fix[n];
xnn.imag[n] = 0;
}
dft_fix(&xnn,&Xkk,N);
printf ("DFT Fixed Point done\n");
idft_fix(&xcc,&Xkk,N);
printf ("IDFT Fixed Point done\n");
}
void dft_fix(complex_fix *g,complex_fix *G,int len)
{
int n,k;
float alp,alpha,angle =0;
int cf,sf;
long prod1,prod2,sum1 = 0,sum2 = 0;
alp = (2*PI/N);
for (k=0;k<len;k++)
{
G->real[k] = 0;
G->imag[k] = 0;
alpha = alp*k;
angle = 0;
sum1 = 0;
sum2 = 0;
for(n=0;n<len;n++)
{
cf = cos(angle)*Q14; //SI1F14
sf = sin(angle)*Q14; //SI1F14
prod1 = ((long)cf*(long)g->real[n]); //SSI1F29
prod1 += ((long)sf*(long)g->imag[n]); //SSI1F29
prod1 = prod1<<1; //SI1F30
prod2 = ((long)cf*(long)g->imag[n]); //SSI1F29
prod2 -= ((long)sf*(long)g->real[n]); //SSI1F29
prod2 = prod2<<1; //SI1F30
sum1 = sum1+(prod1>>5); //SI6F25
sum2 = sum2+(prod2>>5); //SI6F25
angle = angle+alpha;
}
G->real[k] = (int)(sum1>>16); //SI6F9
chk_real_fix_dft[k] = (float)G->real[k]/(Q15>>6);
G->imag[k] = (int)(sum2>>16); //SI6F9
chk_imag_fix_dft[k] = (float)G->imag[k]/(Q15>>6);
}
}
void idft_fix(complex_fix *g,complex_fix *G,int len)
{
int n,k;
float alp,angle=0,alpha;
int cf,sf;
long prod1,prod2,sum1=0,sum2=0;
alp = (2*PI/N);
for(n=0;n<len;n++)
{
g->real[n] = 0;
g->imag[n] = 0;
alpha = alp*n;
angle = 0;
sum1 =0;
sum2 = 0;
for(k=0;k<len;k++)
{
cf = cos(angle)*Q14; //SI1F14
sf = sin(angle)*Q14; //SI1F14
prod1 = ((long)cf*(long)G->real[k]); //SSI7F23
prod1 -= ((long)sf*(long)G->imag[k]);
prod1 = prod1<<1; //SI7F24
prod2 = ((long)cf*(long)G->imag[k]);
prod2 += ((long)sf*(long)G->real[k]); //SSI7F23
prod2 = prod2<<1; //SI7F24
sum1 = sum1 + (prod1>>5); //SI12F19
sum2 = sum2 + (prod2>>5); //SI12F19
angle = angle +alpha;
}
g->real[n] = (int)(sum1>>16); //SI7F8
chk_real_fix_idft[n] = (float)g->real[n]/(Q15>>7); //for testing CCS calculating with MATLAB Calculation
g->imag[n] = (int)(sum2>>16);
chk_imag_fix_idft[n] = (float)g->imag[n]/(Q15>>7); //for testing CCS calculation with MATLAB Calculation
}
}