Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
The transformation of discrete data between the time and frequency domain is
quite useful in extracting information from the signal. The DFT expresses signals as a
linear combination of sinusoidal or complex exponential signals with various angular
frequencies. This decomposition of signals allows one to examine the effects of the
system on each signal component. It is based on the Fourier series, which is a linear
weighted sum of harmonically related sinusoids and complex exponentials. The DFT
and its fast computational algorithm, the fast Fourier transform (FFT) are among the
most important tools in signal processing. The DFT is commonly applied to
implement linear filtering, spectral analysis, and correlation analysis.
We first review the Fourier series and the Fourier transform before proceeding
with the DFT.
Unlike the Fourier series, the Fourier transform does not require that the signal be
periodic [21].
where
WN = e − j 2 π / N (4.6)
The factor W, also known as the twiddle factor, is a function of N frequency terms
with argument kn which can take on any integer value up to (N-1)2 [20, 23]. Each
point of the DFT in equation (4.5) can be calculated using N complex multiplications
and (N-1) complex additions. Therefore, N2 complex multiplications and N(N-1)
complex additions are needed to compute N DFT values [5]. If we count two real
sums for every complex one, and four real multiplications plus two real summations
for every complex multiplication then we need a total of 4N2-2N real summations and
4N2 real multiplications to compute the N DFT values.
The inverse discrete Fourier transform (IDFT) is given by
N −1
1
x[n] =
N
∑ X ( k )W
k =0
− kn
N , n = 0, 1, ... , N − 1 (4.7)
We can see from equation (4.5) and (4.7) that the only difference between the DFT and
the IDFT is the factor of 1/N and the negative exponent in the IDFT [21]. Therefore,
where WN is the N×N matrix of linear transformation, xN is the N-point vector of the
signal x[n], and XN is the N-point vector of frequency samples defined by
1 1 1 . . . 1
1 W WN2 . . . W N −1
N N
WN2 WN42 . . . W 2 ( N − 1)
N
WN = . . . . . . .
. . . . . . .
. . . . . . .
N −1 2 ( N − 1) ( N − 1)( N −1)
(4.9)
1 WN WN . . . WN
x (0) X (0)
x (1) X (1)
xN = . , XN = .
. .
x ( N − 1) X ( N − 1)
In the same terms, the IDFT is given by
1
xN = WN* X N (4.10)
N
where W*N is the complex conjugate of WN.
where
The polynomial calculation can be rewritten as a difference equation [21] in the form
of
y[n ] = zy[n − 1] + x[ N − n ] (4.13)
At n=N, the Goertzel algorithm is written in the form of a first order filter as
y[n ] = W k y[n − 1] + x[ N − n ], y ( −1) = 0 (4.14)
with
X ( k ) = y[ N ] (4.15)
Figure (4.1) shows the Goertzel algorithm as a recursive filter.
y(n)
[n]
[N-n)
x(N-n) [n-1]
y(n-1)
DELAY z-1
Wk
The Goertzel algorithm is only efficient if the DFT is to be computed for less than
log2(N) elements [21].
The symmetry properties of the DFT are described in detail in [5, 25].
Example 4.1:
We first develop and implement a direct method to compute the DFT and IDFT
on the ‘C40. Files hprg4_1.c and dprg4_1.c implement this algorithm. Please note
100
80
60
40
20
0
0 50 100 150 200
π0.1n)
Figure 4.2 DFT of x(n)=cos(2π
Example 4.2:
We modify hprg4_1.c and dprg4_1.c to use the complex structure. This will
enable to us compute more efficiently. This does not involve using two separate arrays
for the real and imaginary parts but rather uses a common C structure of the form
typedef struct {
float real;
float imag;
} complex
This enables us to use the data in the form
x[n].real and x[n].imag
Great care is needed in coding algorithms using complex structure for ‘C40. C can
also use double instead of float but this will not work for ‘C40 implementation using
Sonitech’s board. Also the values uploaded from the ‘C40 to the pentium host program
should be at least two times the size of data points to accommodate for real and
imaginary points. Files hprg4_1a.c and dprg4_1a.c are used for implementation.
Recommended Exercises
2. Modify hprg4_1.c and dprg4_1.c to read and write the input and the output
from data files. Generate a sequence [3] based on the following equation in
MATLAB.
x[n] = Qn , n = 0, 1, ... , 31
where
Q = 0.9 + j0.3
Save this sequence in a data file and compute the DFT. (Hint: Use “save”
command in MATLAB to create a data file. Use “help save” in MATLAB for
further information.)
Plot the absolute value of DFT.
There are many types of FFT algorithms available. We discuss four of the
most commonly used algorithms.
Let a sequence {x[n]} be separated into two N/2-point sequences [27] with one
corresponding to the even-numbered {y[n]} and the second representing odd-
numbered {z[n]} samples of x[n] as shown by equation (4.17).
y[n] = x[2n]
N (4.17)
z[n] = x[2n + 1], n = 0, 1, ... , −1
1
Using equation (4.18), we can rewrite equation (4.5) as
( N / 2 ) −1 ( N / 2 ) −1
X (k ) = ∑ y[n]WNk 2n +
n=0
∑ z[n]W
n=0
k ( 2 n +1)
N , k = 0, 1, ... , N − 1 (4.18)
or
( N / 2 ) −1 ( N / 2 ) −1
X (k ) = ∑ y[n]W k 2n
N +WNk ∑ z[n]W k 2n
N , k = 0, 1, ... , N − 1 (4.19)
n=0 n=0
But W2N = WN/2 [3]. Using this equality in equation (4.19) we get
( N / 2 ) −1 ( N / 2 ) −1
X (k ) = ∑ y[n]W kn
N /2 +Wk
N ∑ z[n]W kn
N /2 , k = 0, 1, ... , N − 1 (4.20)
n=0 n=0
and
X ( k ) = Y ( k ) + WNk Z ( k ) (4.21)
Since Y(k) and Z(k) are periodic in the half interval N/2, we can rewrite equation (4.21)
using this periodic property and the factor WNk+N/2 = -WkN as
N N
X k + = Y ( k ) − WNk Z ( k ), k = 0, 1, ... , −1 (4.22)
2 2
We observe that N-point DFT is computed using two length (N/2) DFTs and some
extra operations called butterfly operations. Figure (4.3) shows one of the butterfly
operation. Each of these butterflies is a length 2 DFT breaking a length N DFT up into
a two-dimensional length (2×N/2) DFT. It involves one complex multiplication and
two complex additions.
Wr N
b a-bWrN
-1
x[4] x[1]
-1
W 0N
x[2] x[2]
-1
W 2N
x[6] x[3]
-1 -1
W 0N
x[1] x[4]
-1
W 1N
x[5] x[5]
-1 -1
W 0N W 2N
x[3] x[6]
-1 -1
W 2N W 3N
x[7] x[7]
-1 -1 -1
Then we have
( N / 2 ) −1 N −1
X (k ) = ∑ y[n]WNkn +
n=0
∑ z[n]W
n= N /2
kn
N (4.24)
Using equation (4.23) and the property WNkN/2 = (-1)k, we can rewrite equation (4.24)
as
where
N
k = 0, 1, ... , −1 (4.26)
2
Now, we can split X(k) into even- and odd-numbered samples by using W2N = WN/2 as
( N / 2 ) −1
X (2 k ) = ∑ [ y[n] + z[n]]W kn
N /2
n=0
( N / 2 ) −1
(4.27)
X (2 k + 1) = ∑ {[ y[n] − z[n]]W }W n
N
kn
N /2
n=0
Again, the N-length DFT can be computed using two length (N/2) DFTs. Figure (4.5)
shows the signal flow graph for 8-point radix-2 DIF FFT.
x[0] x[0]
x[1] x[4]
-1
W 0N W 0N
x[2] x[2]
-1
W 0N
x[3] x[6]
-1 -1
W 0N
x[4] x[1]
-1
W 1N
x[5] x[5]
-1 -1
W 2N W 0N
x[6] x[3]
-1 -1
W 3N W 2N
x[7] x[7]
-1 -1 -1
Figure 4.5 Signal Flow Graph for 8-Point Radix-2 DIF FFT
We can see that the DIF requires the same number of multiplications and additions
that are required by the DIT FFT. It has input samples in natural (unshuffled) order
and yields frequency samples in bit-reversed (shuffled) order [27]. Figure (4.6) shows
a a+b
WrN
b (a-b)WrN
Figure (4.7) shows the signal flow graph for a radix-4 DIT FFT. The input order in
this figure is obtained by reversing the base-4 representation; e.g., 6 = 124, which
reverses to 214 = 9. This method requires (9/4)N log2 (N) - (43/12)N +(16/3) real
multiplications and (25/4)N log2 (N) -(43/12)N + 16/3 real additions, assuming that the
complex multiplications are done using three real multiplications and three additions.
The radix-4 FFT is used to reduce the number of complex multiplications by a factor
of almost 2. Furthermore the number of additions is also reduced. All this increases
the computational speed for the FFT algorithms.
x[4] x[1]
x[8] x[2]
x[12] x[3]
x[1] x[4]
W0N
x[5] x[5]
W1 N
x[9] x[6]
W2 N
x[13] x[7]
W3 N
x[2] x[8]
W0N
x[6] x[9]
W2 N
x[10] x[10]
W4N
x[14] x[11]
W6N
x[3] x[12]
W0N
x[7] x[13]
W3 N
x[11] x[14]
W6N
x[15] x[15]
W9N
Figure 4.7 Signal Flow Graph for a Radix-4 DIT FFT [24]
x[0] x[0]
x[1] x[4]
x[2] x[8]
x[3] x[12]
x[4] x[1]
x[5] x[5]
x[6] x[9]
x[7] x[13]
x[8] x[2]
x[9] x[6]
x[10] x[10]
x[11] x[14]
x[12] x[3]
x[13] x[7]
x[14] x[11]
x[15] x[15]
x[0] x[0]
x[1] x[8]
W 0N
x[2] x[4]
W0N
x[3] x[12]
x[4] x[2]
x[5] x[10]
x[6] x[6]
x[7] x[14]
W0 N
x[8] x[1]
W 1N
x[9] x[9]
W2N W 0N
x[10] x[5]
W3 W0N
N x[13]
x[11]
W0N
x[12] x[3]
W 3N
x[13] x[11]
W 6N W 0N
x[14] x[7]
W9N W 0N
x[15] x[15]
Example 4.4:
Example 4.5:
We now implement another method of implementing a FFT for real data. Files
hprg4_5.c and dprg4_5.c are used in this sample implementation. This FFT routine
accomplishes the in-place transformation of a real sequence of length N in a storage
area using the method given by Brogham [41]. In this method the original real
sequence of N points is viewed as a complex sequence of N/2 points.
[x[0], x[1], ... , x[N-1]] = [uo , u1 , ... , uN/2-1]
We implemented the following test sequence on this algorithm
x[n] = {-6, -2, 0, 2, 4, 6, 3, -1}
which resulted in the following output
Real Imaginary
6.0 0.0
-17.7782 6.5355
-5.0 -3.0
-2.2218 0.5355
-4.0 0.00
We used this program to compute the FFT of the following hypothetical voltage
waveform sequence.
0.8
0.6
0.4
0.2
-0.2
-0.4
-0.6
0 200 400 600 800 1000 1200
Figure (4.11) shows the FFT plot of the first 100 values.
80
70
60
50
40
30
20
10
0
0 10 20 30 40
Example 4.6:
Files hprg4_7.c and dprg4_7.c implement the inverse FFT using REAL data.
The transformations are in place and N has to be power of 2. We later combined this
program structure with the programs used in Example (4.5) into one big program using
two ‘C40s. This results in a flexible program.
Example 4.7:
In this example, we implement the FFT computations on complex input data.
Files hprg4_8.c and dprg4_8.c are created for this implementation. The complex
computation requires twice the storage size as compared to the implementations
discussed in Example (4.5) and Example (4.6). The computation is in place requiring
N to be a power of 2. The basic algorithm here is an extension of Cooley-Tukey
algorithm [26]. The output has two main parts in it; spectral component and the
output time series, which is N times the original data. In our actual program output
column 2nd and 3rd belong to the output time series whereas the spectral components
are in column 4th and 5th. Please note that column 4th is the real part and column 5th
is the imaginary pert of the data.
Example 4.8:
We now implement the Radix-4 FFT. Files hprg4_3.c and dprg4_3.c are used
in this sample implementation. This implementation is based on Cooley-Tukey Radix-
4 DIF FFT program [21, 26]. The real part of the input data is in array x whereas the
imaginary part in array y. In this implementation, the length of input data should be
equal or greater to the FFT length n. The program was tested for the following data.
x(n) = {1, 2, 3, 4}
Recommended Exercises
1. Modify the programs in files hprg4_4.c and dprg4_4.c to find the DIF and DIT
Radix-2 FFT of the following sequence. Plot the FFT using MATLAB.
x(n)=cos(2π(0.1)n), n = 1, ...., 100
4. Combine into one, the FFT and IFFT of real sequences( Files are hprg4_5.c,
hprg4_6.c, dprg4_5.c, dprg4_6.c). Use ‘C40 # 1 to implement the FFT and
‘C40 # 2 for the IFFT.
The prime factor map for time and frequency are given by
N N N
n≡ M1n1 + M 2 n2 + . . . + M Q nQ ,
N1 N2 NQ
N
(4.31)
N N N
k≡ k1 + k2 + . . . + kQ .
N1 N2 NQ
N
[ ]
X k1 , k 2 ,..., k Q =
n1 = 0 n2 = 0 nQ = 0
[ ]
∑ ∑ ..... ∑ x n1 , n2 ,..., nQ ⋅ WNn11k1WNn22k2 ...WNQQ Q
n k
(4.32)
rxy(n) is the cross-correlation function of x[k] and x[k] and rxx(n) is the autocorrelation
function of x[k]. The cross-correlation function is a very sensitive measure of the
-5
0 50 100 150 200 250 300
Figure 4.13 First 300 Samples of Sine Wave with Added Uniform White Noise
The autocorrelation sequence results are stored in file hprg4_9o.dat from where they
are plotted using MATLAB. Figure (4.14) shows the autocorrelation result of the first
10000
8000
6000
4000
2000
-2000
0 50 100 150 200 250 300
Figure 4.14 Autocorrelation Function of the Sine Wave With Added White Noise
0.8
0.6
0.4
0.2
-0.2
-0.4
-0.6
0 200 400 600 800 1000
0
0 200 400 600 800 1000
The input signal is generated in array x and the system’s impulse response in y. Figure
(4.17) describes the convolution results.
-2
-4
0 200 400 600 800 1000
The impulses in figure (4.17) represent various reflectors. These reflectors are actually
resulting in different paths from transmitter to receiver causing the input signal to be
added with different delays and different strengths at the output.
0.5
-0.5
-1
0 10 20 30 40
0
0 0.1 0.2 0.3 0.4 0.5
1.5
0.5
x(N)
-0.5
-1
-1.5
-2
0 100 200 300 400 500
N
Figure 4.20 Input Sequence with Two Sinusoids and Uniform White Noise
We can see from figure (4.20) that the sinusoidal components are hardly visible. We
apply the Periodogram method and figure (4.21) plots the output in dB scale
10
-10
-20
-30
-40
-50
0 0.1 0.2 0.3 0.4 0.5
Figure 4.21 Power Spectrum of Two Sine Waves plus Added Noise (Sampling
Frequency is 1)
It is evident from figure (4.21) that the average Periodogram method was able to
identify the two peaks at frequencies 3/32 and 7/32 Hz-s.
25
20
15
10
0
0 500 1000 1500 2000 2500 3000
Frequency
Figure 4.22 Power Density Spectrum of Voice Data File ltlchk.dat
Application Exercises
2. Use the convolution algorithm files to compute 100 samples of the output of
the following filter [41, 21]:
2πk 0.25 + 0.25z-1 + 0.25z-2
sin
16
4. Try running Periodogram using the data hubble.dat. Do you get the following
power density spectrum assuming sampling frequency of 1.
-20
-40
-60
-80
-100
-120
0 0.1 0.2 0.3 0.4 0.5
5. Use the file input.dat from chapter 2 and plot the power density spectrum.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "c:\spirit40\source\s40tools.h"
#define size 16 /* This code will work for a max size of 600 */
#define pi 3.141592654
#define maxbits 30
int inv;
long npt;
float x[size], y[size],xx[size],yy[size];
void main()
{
int status;
int n;
long k;
int k2;
y[1]=0;
y[2]=0;
y[3]=0;
y[4]=0;
y[5]=0;
y[6]=0;
y[7]=0;
y[8]=0;
dsp_select(1);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg4_1.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
x_addr=dsp_get_laddr("_x");
y_addr=dsp_get_laddr("_y");
xx_addr=dsp_get_laddr("_xx");
yy_addr=dsp_get_laddr("_yy");
flag_addr=dsp_get_laddr("_flag");
dsp_dl_long_array(x_addr,size,(long*)x);
dsp_dl_long_array(y_addr,size,(long*)y);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(xx_addr,size,(long*)&xx);
dsp_up_long_array(yy_addr,size,(long*)&yy);
printf("\n");
for (k=1;k<=npt;++k){
k2=k-1;
printf("%d \t%f \t%f \n",k2, xx[k], yy[k]);
}
}
#include "c:\sim4x\math.h"
#include "c:\sim4x\stdlib.h"
#define size 16
#define pi 3.141592654
#define maxbits 30
main()
{
long k,n;
init_c40();
while (flag!=1);
dsp30(x,size);
dsp30(y,size);
WN=2*pi/npt;
if (inv==1)
WN=-WN;
for(k=0;k<npt;++k){
XR[k]=0.0;XI[k]=0.0;
wk=k*WN;
for (n=0;n<npt;++n){
c=cos(n*wk);s=sin(n*wk);
XR[k]=XR[k]+x[n+1]*c+y[n+1]*s;
XI[k]=XI[k]-x[n+1]*s+y[n+1]*c;
}
if (inv==1){
XR[k]=XR[k]/npt;
XI[k]=XI[k]/npt;
}
}
for (k=1;k<=npt;++k){
xx[k]=XR[k-1];
yy[k]=XI[k-1];
}
ieee30(xx,size);
ieee30(yy,size);
flag=0;
while(1);
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "c:\spirit40\source\s40tools.h"
#define N 5
#define NN 3
void main()
{
int status;
int ord;
int k;
float x[NN]={1,2,3}, y[NN]={0,0,0};
float a[N],b[N];
printf("\n\n\t***Goertzel Computation of DFT***\n\n");
printf("Enter 1 for DFT first order and 2 for DFT second order= ");
scanf("%d",&ord);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg4_2.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
x_addr=dsp_get_laddr("_x");
y_addr=dsp_get_laddr("_y");
ord_addr=dsp_get_laddr("_ord");
a_addr=dsp_get_laddr("_a");
b_addr=dsp_get_laddr("_b");
flag_addr=dsp_get_laddr("_flag");
dsp_dl_long_array(x_addr,NN,(long*)x);
dsp_dl_long_array(y_addr,NN,(long*)y);
dsp_dl_int_array(ord_addr,1,(int*)ord);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(a_addr,N,(long*)a);
dsp_up_long_array(b_addr,N,(long*)b);
printf("\n");
printf("The Goertzel DFT is...\n");
for (k=0;k<N;++k){
printf("%d \t%f \t%f \n",k, a[k], b[k]);
}
}
#include "c:\sim4x\math.h"
#define N 5 /* N -point DFT */
#define NN 3
int flag=0,ord;
float x[NN], y[NN], a[N], b[N];
main()
{
float cc,a2,a1,b2,b1,at,s,c,bt,q,t;
int k,j,i;
init_c40();
while (flag!=1);
dsp30(x,NN);
/* goertzel algorithm */
if (ord==1){
q=6.283185307179586/N;
for (j=0;j<N;++j){
c=cos(q*j);
s=sin(q*j);
at=x[N-1];
bt=y[N-1];
for (i=0;i<N-2;++i){
t=c*at+s*bt+x[N-(i+2)];
bt=c*bt-s*at+y[N-(i+2)];
at=t;
}
a[j]=c*at+s*bt+x[0];
b[j]=c*bt-s*at+y[0];
}
}
else {
q=6.283185307179586/N;
for (j=0;j<N;++j){
s=sin(q*j);
c=cos(q*j);
cc=2*c;
a2=0;
b2=0;
a1=x[N-1];
b1=y[N-1];
for (i=0;i<N-2;++i){
t=a1;
a1=cc*a1-a2+x[N-(i+2)];
a2=t;
t=b1;
b1=cc*b1-b2+y[N-(i+2)];
b2=t;
}
a[j]=c*a1-a2-s*b1+x[0];
b[j]=s*a1+c*b1-b2+y[0];
}
}
ieee30(&a,N);
ieee30(&b,N);
flag=0;
while(1);
}
#include "c:\sim4x\math.h"
#define size 600
#define pi 3.141592654
typedef struct {
float real;
int flag=0;
int inv;
int npt;
int k,n;
float WN, wk, c, s, XR[size], XI[size];
complex x[size];
complex xx[size];
main()
{
int k;
init_c40();
while (flag!=1);
dsp30(x,npt*npt);
WN=2*pi/npt;
if (inv==1)
WN=-WN;
for(k=0;k<npt;++k){
XR[k]=0.0;XI[k]=0.0;
wk=k*WN;
for (n=0;n<npt;++n){
c=cos(n*wk);s=sin(n*wk);
XR[k]=XR[k]+x[n].real*c+x[n].imag*s;
XI[k]=XI[k]-x[n].real*s+x[n].imag*c;
}
if (inv==1){
XR[k]=XR[k]/npt;
XI[k]=XI[k]/npt;
}
}
for (k=0;k<npt;++k){
xx[k].real=XR[k];
xx[k].imag=XI[k];
}
ieee30(xx,npt*npt);
flag=0;
while(1);
}
#include "c:\sim4x\math.h"
#define size 600
#define pi 3.141592654
typedef struct {
float real;
float imag;
}complex;
int flag=0;
int inv;
int npt;
int k,n;
complex x[size];
complex xx[size];
main()
{
int k;
init_c40();
while (flag!=1);
dsp30(x,npt*npt);
WN=2*pi/npt;
if (inv==1)
WN=-WN;
for(k=0;k<npt;++k){
XR[k]=0.0;XI[k]=0.0;
wk=k*WN;
for (n=0;n<npt;++n){
c=cos(n*wk);s=sin(n*wk);
XR[k]=XR[k]+x[n].real*c+x[n].imag*s;
XI[k]=XI[k]-x[n].real*s+x[n].imag*c;
}
if (inv==1){
XR[k]=XR[k]/npt;
XI[k]=XI[k]/npt;
}
}
for (k=0;k<npt;++k){
xx[k].real=XR[k];
xx[k].imag=XI[k];
}
ieee30(xx,npt*npt);
flag=0;
while(1);
}
/* FFT-Radix-4 DIF */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include "c:\spirit40\source\s40tools.h"
void main()
{
int i,status,n,m;
float x[4]={1,2,3,4};
float y[4]={0,0,0,0};
m=1;
n=pow(4,m); /* length of data is greater and equal to n */
dsp_select(1);
printf("\nC40 #1 is selected.....\n\n");
if (dsp_dl_exec("dprg4_3.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
x_addr=dsp_get_laddr("_x");
y_addr=dsp_get_laddr("_y");
flag_addr=dsp_get_laddr("_flag");
m_addr=dsp_get_laddr("_m");
n_addr=dsp_get_laddr("_n");
dsp_dl_long_array(x_addr,n,(long*)x);
dsp_dl_long_array(y_addr,n,(long*)y);
dsp_dl_int_array(m_addr,1,(int*)&m);
dsp_dl_int_array(n_addr,1,(int*)&n);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(x_addr,n,(long*)x);
dsp_up_long_array(y_addr,n,(long*)y);
int m,n,n2,k,n1,j,i,i1,i2,i3;
float e,a,c01,c02,si1,si2,b,c,c03,si3,r3,r1,r2,s1,s3,r4,s2,s4,x[4],y[4];
int flag=0;
main()
{
init_c40();
dsp30(x,4);
dsp30(y,4);
n2=n;
for (k=0;k<m;++k){
n1=n2;
n2=n2/4;
e=6.283185307179586/n1;
a=0;
for (j=0;j<n2;++j){
b=a+a;
c=a+b;
c01=cos(a);
c02=cos(b);
c03=cos(c);
si1=sin(a);
si2=sin(b);
si3=sin(c);
a=j*e;
for (i=j;i<n;i+=n1){
i1=i+n2;
i2=i1+n2;
i3=i2+n2;
r1=x[i]+x[i2];
r3=x[i]-x[i2];
s1=y[i]+y[i2];
s3=y[i]-y[i2];
r2=x[i1]+x[i3];
r4=x[i1]-x[i3];
s2=y[i1]+y[i3];
s4=y[i1]-y[i3];
x[i]=r1+r2;
r2=r1-r2;
r1=r3-s4;
r3=r3+s4;
y[i]=s1+s2;
s2=s1-s2;
s1=s3+r4;
s3=s3-r4;
x[i1]=c01*r3+si1*s3;
y[i1]=c01*s3-si1*r3;
x[i2]=c02*r2-si2*r2;
y[i2]=c02*s2-si2*r2;
x[i3]=c03*r1+si3*s1;
y[i3]=c03*s1-si3*r1;
}
}
}
k=k/4;
goto g2;
g3: j=j+k;
}
ieee30(&x,4);
ieee30(&y,4);
flag=0;
while(1);
}
/* HPRG4_4.C */
/* Cooley-Tukey FFT Radix-2 DIF and DIT */
/* x array of real part of input length >=N */
/* y array of real part of input length >=N */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include "c:\spirit40\source\s40tools.h"
#define N 4 /* since N=2**m */
int m=2;
float xx[N],yy[N];
float x[N]={1,2,3,4}, /* Sample Input data */
y[N]={0,0,0,0};
void main()
{
int status,ch;
int k,i;
dsp_select(1);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg4_4.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
x_addr=dsp_get_laddr("_x");
y_addr=dsp_get_laddr("_y");
xx_addr=dsp_get_laddr("_xx");
yy_addr=dsp_get_laddr("_yy");
ch_addr=dsp_get_laddr("_ch");
m_addr=dsp_get_laddr("_m");
flag_addr=dsp_get_laddr("_flag");
dsp_dl_long_array(x_addr,N,(long*)x);
dsp_dl_long_array(y_addr,N,(long*)y);
dsp_dl_int_array(ch_addr,1,(int*)&ch);
dsp_dl_int_array(m_addr,1,(int*)&m);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(xx_addr,N,(long*)&xx);
dsp_up_long_array(yy_addr,N,(long*)&yy);
printf("\n");
for (k=0;k<N;++k){
printf("%d \t%f \t%f \n",k, xx[k], yy[k]);
}
ofp=fopen("fftdtdf.dat","w");
printf("The result was written in file 'fftdtdf.dat'....\n");
for (i=0;i<N;++i)
fprintf(ofp, "%f %f\n", xx[i],yy[k]);
fclose(ofp);
}
#include "c:\sim4x\math.h"
#define N 4
int ch,flag=0;
int n2,k,n1,j,l,i,m;
float e,a,c,s,xt,yt;
float x[N],y[N],xx[N],yy[N];
main()
{
init_c40();
while (flag!=1);
dsp30(x,N);
dsp30(y,N);
l3: j=j+k;
}
n1=1;
for (k=0;k<m;++k){
n2=n1;
n1=n2*2;
e=6.283185037179586/n1;
a=0;
for (j=0;j<n2;++j){
c=cos(a);
s=sin(a);
a=(j+1)*e;
for (i=j;i<N;i=i+n1) {
l=i+n2;
xt=c*x[l]+s*y[l];
yt=c*y[l]-s*x[l];
x[l]=x[i]-xt;
x[i]=x[i]+xt;
y[l]=y[i]-yt;
y[i]=y[i]+yt;
}
}
}
}
for (j=0;j<N;++j) {
xx[j]=x[j];
yy[j]=y[j];
}
ieee30(xx,N);
ieee30(yy,N);
flag=0;
while(1);
}
/* HPRG4_5.C */
/* FFT Computation */
/* Real Data
N=power of 2
Storage N+2 real */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
float x[10] = { -6.0, -2.0, 0.0, 2.0, 4.0, 6.0, 3.0, -1.0, 0.0, 0.0};
long x_addr, flag_addr,xx_addr;
float xx[nn+1];
void main()
{
int status,m;
printf("\n\nFFT Real sequence\n\n");
dsp_select(1);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg4_5.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
x_addr=dsp_get_laddr("_x");
xx_addr=dsp_get_laddr("_xx");
flag_addr=dsp_get_laddr("_flag");
dsp_dl_long_array(x_addr,10,(long*)x);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(xx_addr,nn+1,(long *)&xx);
/* DPRG4_5.C */
/* Real Sequence */
#include "c:\sim4x\math.h"
#define PI 3.14159265358979323846
typedef struct {
float r, i;
} complex;
int flag=0;
main()
{
int i;
init_c40();
while (flag!=1);
dsp30(x,10);
spfftr(x, &nn);
for (i=0;i<=nn+1;++i){
xx[i]=x[i];
}
ieee30(xx,nn+1);
flag=0;
while(1);
long m, tmp_int;
complex u, tmp, tmp_complex;
float tpn, tmp_float;
tmp_int = *n / 2;
spfftc(x, &tmp_int, &neg_i1);
return;
}
mr = 0;
mr = mr % l + l;
if (mr > m)
{
t.r = x[m].r;
t.i = x[m].i;
x[m].r = x[mr].r;
x[m].i = x[mr].i;
x[mr].r = t.r;
x[mr].i = t.i;
}
}
l = 1;
tmp_int = l * 2;
complex_exp(&tmp_complex, &tmp);
return;
}
/* complex conjugate */
void r_cnjg(complex *r, complex *z)
{
r->r = z->r;
r->i = -z->i;
}
/* complex exponential */
void complex_exp(complex *r, complex *z)
{
double expx;
/* HPRG4_6.C */
/* FFT Radix-8 Computation */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "c:\spirit40\source\s40tools.h"
#define nn 8
FILE *ofp;
void main()
{
int status,i;
printf("\n\nFFT Radix-8\n\n");
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg4_6.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
x_addr=dsp_get_laddr("_x");
y_addr=dsp_get_laddr("_y");
xx_addr=dsp_get_laddr("_xx");
yy_addr=dsp_get_laddr("_yy");
flag_addr=dsp_get_laddr("_flag");
dsp_dl_long_array(x_addr,nn,(long*)x);
dsp_dl_long_array(y_addr,nn,(long*)y);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(xx_addr,nn,(long *)&xx);
dsp_up_long_array(yy_addr,nn,(long *)&yy);
ofp=fopen("hprg4_6.dat","w");
printf("\n\n");
printf("Real Imaginary\n");
for (i=0;i<nn;++i) {
printf("%f %f\n",xx[i],yy[i]);
fprintf(ofp, "%f %f\n", xx[i],yy[i]);
}
fclose(ofp);
printf("The data was saved in hprg4_6.dat\n");
}
/* dprg4_6.c---FFT Radix-8 */
#include "c:\sim4x\math.h"
#define nn 8
int m,n,n2,n1,j,b,c,d,e,f,g,i,jj;
float co2,co3,co4,co5,co6,co7,co8,si2,si3,si4,si5,si6,si7,si8;
int i1,i2,i3,i4,i5,i6,i7,i8;
float r1,r2,r3,r4,r5,r6,r7,r8,s1,s2,s3,s4,s5,s6,s7,s8,t1,t2,k;
float x[nn], y[nn],c81,e1,a,t,xx[nn],yy[nn];
int flag=0;
main()
{
dsp30(x,nn);
dsp30(y,nn);
m=1;
n=pow(8,m);
c81=0.707106778;
n2=n;
for (k=0;k<m;++k) {
n1=n2;
n2=n2/8;
e1=6.283185307179586/n1;
a=0;
for (j=0;j<n2;++j) {
b=a+a;
c=a+b;
d=a+c;
e=a+d;
f=a+e;
g=a+f;
co2=cos(a);
co3=cos(b);
co4=cos(c);
co5=cos(d);
co6=cos(e);
co7=cos(f);
co8=cos(g);
si2=sin(a);
si3=sin(b);
si4=sin(c);
si5=sin(d);
si6=sin(e);
si7=sin(f);
si8=sin(g);
a=(j+1)*e1;
for (i1=j;i1<n;i1=i1+n1) {
i2=(i1)+n2;
i3=(i2)+n2;
i4=(i3)+n2;
i5=(i4)+n2;
i6=(i5)+n2;
i7=(i6)+n2;
i8=(i7)+n2;
r1=x[i1]+x[i5];
r5=x[i1]-x[i5];
r2=x[i2]+x[i6];
r6=x[i2]-x[i6];
r3=x[i3]+x[i7];
r7=x[i3]-x[i7];
r4=x[i4]+x[i8];
r8=x[i4]-x[i8];
t1=r1-r3;
r1=r1+r3;
r3=r2-r4;
r2=r2+r4;
x[i1]=r1+r2;
r2=r1-r2;
s1=y[i1]+y[i5];
a1: k=n/8;
a3: j=j+k;
}
for (jj=0;jj<nn;++jj) {
xx[jj]=x[jj];
yy[jj]=y[jj];
}
ieee30(&xx,nn);
ieee30(&yy,nn);
flag=0;
while(1);
}
• Host File hprg4_7.c
/* HPRG4_7.C */
/* Inverse FFT Computation */
/* Real Data
N=power of 2
Storage N+2 real */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "c:\spirit40\source\s40tools.h"
#define nn 8
float x[10] = { -6.0, -2.0, 0.0, 2.0, 4.0, 6.0, 3.0, -1.0, 0.0, 0.0 };
long x_addr, flag_addr,xx_addr;
float xx[nn];
void main()
{
int status,m;
printf("\n\n\t Inverse FFT of Real sequence\n\n");
printf("the input sequence is...\n");
for (m=0;m<10;m++) printf("\t%f\n",x[m]);
dsp_select(1);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg4_7.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
x_addr=dsp_get_laddr("_x");
xx_addr=dsp_get_laddr("_xx");
flag_addr=dsp_get_laddr("_flag");
dsp_dl_long_array(x_addr,10,(long*)x);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(xx_addr,nn,(long *)&xx);
/* DPRG4_7.C */
/* Inverse FFT--Real Sequence */
#include "c:\sim4x\math.h"
#define pi 3.14159265358979323846
typedef struct {
float r, i;
} complex;
long nn=8;
float x[10];
float xx[9];
long m;
int flag=0;
main()
{
long i;
init_c40();
while (flag!=1);
dsp30(x,10);
spfftr(x, &nn);
spiftr(x, &nn);
ieee30(xx,nn+1);
flag=0;
while(1);
}
tmp_int = *n / 2;
spfftc(x, &tmp_int, &neg_i1);
return;
}
x[m].r = tmp_float;
return;
}
mr = 0;
mr = mr % l + l;
if (mr > m)
l = 1;
tmp_int = l * 2;
complex_exp(&tmp_complex, &tmp);
return;
}
void complex_exp(complex *r, complex *z)
{
double expx;
/* HPRG4_8.C */
/* FFT Computation */
/* Complex data
N=power of 2
Storage N complex */
void main()
{
int status,m;
printf("\n\n\t FFT of Complex sequence\n\n");
dsp_select(1);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg4_8.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
x1_addr=dsp_get_laddr("_x1");
x2_addr=dsp_get_laddr("_x2");
flag_addr=dsp_get_laddr("_flag");
dsp_dl_long_array(x1_addr,nn*2,(long*)x1);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(x1_addr,nn*2,(long *)&x1);
dsp_up_long_array(x2_addr,nn*2,(long *)x2);
/* DPRG4_8.C */
/* FFT--Complex Sequence */
#include "c:\sim4x\math.h"
#define pi 3.14159265358979323846
typedef struct {
float r, i;
} complex;
complex x1[4];
complex x2[4];
long m;
int flag=0;
main()
{
init_c40();
while (flag!=1);
dsp30(x1,4*2);
ieee30(x1,4*2);
ieee30(x2,4*2);
flag=0;
while(1);
}
mr = 0;
mr = mr % l + l;
if (mr > m)
{
t.r = x[m].r;
t.i = x[m].i;
x[m].r = x[mr].r;
x[m].i = x[mr].i;
x[mr].r = t.r;
x[mr].i = t.i;
}
}
l = 1;
tmp_int = l * 2;
complex_exp(&tmp_complex, &tmp);
return;
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include "c:\spirit40\source\s40tools.h"
int p1 = 1;
int p2 = 300;
int p3 = 2049;
void main()
{
int status;
seed = 100;
number_points = 300;
save_file(x,&number_points,&p1,"hprg4_9i");
printf("The input data was saved in hprg4_9i.dat\n");
dsp_select(1);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg4_9.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
x_addr=dsp_get_laddr("_x");
flag_addr=dsp_get_laddr("_flag");
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
printf("\nThe data is being uploaded..\n");
dsp_up_long_array(x_addr,300,(long*)x);
save_file(x,&number_points,&p1,"hprg4_9o");
printf("The output data was saved in hprg4_9o.dat\n");
}
sprintf(filename,"%s.DAT",name);
fp = fopen(filename,"w+");
/* DPRG4_9.C */
/* COrrelation/Autocorrelation */
#include "c:\sim4x\math.h"
#define pi 3.14159265358979323846
typedef struct {
long i0 = 0;
long p1 = 1;
long P2 = 300;
long P3 = 2049;
void spcorr();
long error, k, number_points;
float x[2050];
int flag=0;
main()
{
int i;
init_c40();
while (flag!=1);
dsp30(x,2050);
ieee30(x,300);
flag=0;
while(1);
void spcorr(float *x, float *y, long *l, long *type, long *nmax, long *error)
{
void spfftr(), spiftr();
long j, k, m, n;
complex cx;
float test;
n = *l - 1;
if (*nmax < 0 || *nmax >= n)
{
*error = 2;
return;
}
test = (float) n;
test /= 2.0;
if ((test - 2.0) == 0)
{
for (k = 0 ; k < n && y[k] == 0.0 ; ++k) ;
spfftr(x, &n);
if (*type != 0)
{
spfftr(y, &n);
}
x[m * 2] = cx.r / n;
x[(m * 2) + 1] = cx.i / n;
}
spiftr(x, &n);
*error = 0;
}
else if ((test - 2.0) < 0.0)
{
*error = 1;
}
return;
}
tmp_int = *n / 2;
spfftc(x, &tmp_int, &neg_i1);
return;
}
mr = 0;
mr = mr % l + l;
if (mr > m)
{
t.r = x[m].r;
t.i = x[m].i;
x[m].r = x[mr].r;
x[m].i = x[mr].i;
x[mr].r = t.r;
x[mr].i = t.i;
}
}
l = 1;
tmp_int = l * 2;
return;
}
x[m].r = tmp_float;
return;
}
/* HPRG41_0.C */
/* Convolution based on FFT */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include "c:\spirit40\source\s40tools.h"
float coeff[8] = { 8.0, 4.0, 7.0, 2.0, 6.0, 3.0, 1.0, 1.0 };
void main()
{
int status;
int k,number_points;
static float x[2050], y[2050];
if (k > 400)
{
x[k] = 0.0;
}
y[k] = 0.0;
/* System's impulse response */
if (k <= 700 && k % 100 == 0)
{
y[k] = coeff[k / 100];
}
}
dsp_select(1);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg41_0.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
x_addr=dsp_get_laddr("_x");
y_addr=dsp_get_laddr("_y");
flag_addr=dsp_get_laddr("_flag");
dsp_dl_long_array(x_addr,p2,(long*)&x);
dsp_dl_long_array(y_addr,p2,(long*)&y);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(x_addr,1000,(long*)x);
save_file(x,&number_points,&p1,"prg41_0");
}
sprintf(filename,"%s.DAT",name);
fp = fopen(filename,"w+");
typedef struct {
float r, i;
} complex;
int flag=0;
main()
{
init_c40();
while (flag!=1);
dsp30(x,32);
dsp30(f0,1);
ieee30(y,17);
flag=0;
while(1);
void sppowr(float *x, float *y, float *work, long *lx, long *ly, long *iwindo, float *ovrlap, long *nsgmts, long
*error)
{
if ((base - 2.0) == 0)
{
for (m = 0 ; m <= *ly ; ++m)
tmp_int = (*ly * 2) - 1;
spmask(work, &tmp_int, iwindo, &tsv, error);
if (*error != 0)
{
return;
}
tmp_int = *ly * 2;
spfftr(work, &tmp_int);
return;
}
void spmask(float *x, long *lx, long *type, float *tsv, long *error)
{
double spwndo();
long k, tmp_int;
double w;
*tsv = 0.0;
for (k = 0 ; k <= *lx ; ++k)
{
tmp_int = 1 + *lx;
w = spwndo(type, &tmp_int, &k);
x[k] *= (float) w;
*tsv += (float) (w * w);
*error = 0;
return;
}
tmp_int = *n / 2;
spfftc(x, &tmp_int, &neg_i1);
return;
}
mr = 0;
mr = mr % l + l;
if (mr > m)
{
t.r = x[m].r;
t.i = x[m].i;
x[m].r = x[mr].r;
x[m].i = x[mr].i;
x[mr].r = t.r;
x[mr].i = t.i;
}
}
l = 1;
tmp_int = l * 2;
complex_exp(&tmp_complex, &tmp);
return;
}
#ifndef KR
void r_cnjg(complex *r, complex *z)
#else
void r_cnjg(r, z)
complex *r, *z;
#endif
{
r->r = z->r;
r->i = -z->i;
}
ret_val = 1.0;
switch (*type)
{
case 1:
break;
case 2:
l = (*n - 2) / 10;
if (*k <= l)
{
ret_val = 0.5 * (1.0 - cos((double) *k * pi
/ ((double) l + 1.0)));
}
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
return(ret_val);
}
/* HPRG41_1.C */
/* Periodogram example */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include "c:\spirit40\source\s40tools.h"
dsp_select(1);
printf("\n\tC40 #1 is selected....\n\n");
if (dsp_dl_exec("dprg41_1.out")==-1){
printf("Error in downloading the file\n");
exit(1);
}
dsp_reset();
dsp_dl_long_array(x_addr,32,(long*)&x);
status=1;
dsp_dl_int_array(flag_addr,1,&status);
while(1){
dsp_up_int_array(flag_addr,1,&status);
if (status==0) break;
if (kbhit()) exit(0);
}
dsp_up_long_array(y_addr,17,(long*)&y);
for (k=0;k<=16;++k) {
printf("%f\n",y[k]);
fprintf(ofp,"%f\n",y[k]);
}
fclose(ofp);
}
typedef struct {
float r, i;
} complex;
int flag=0;
main()
{
init_c40();
while (flag!=1);
dsp30(x,32);
dsp30(f0,1);
ieee30(y,17);
void sppowr(float *x, float *y, float *work, long *lx, long *ly, long *iwindo, float *ovrlap, long *nsgmts, long
*error)
{
if ((base - 2.0) == 0)
{
for (m = 0 ; m <= *ly ; ++m)
{
y[m] = 0.0;
}
tmp_int = (*ly * 2) - 1;
spmask(work, &tmp_int, iwindo, &tsv, error);
if (*error != 0)
{
return;
}
tmp_int = *ly * 2;
spfftr(work, &tmp_int);
return;
}
void spmask(float *x, long *lx, long *type, float *tsv, long *error)
{
double spwndo();
long k, tmp_int;
double w;
*tsv = 0.0;
for (k = 0 ; k <= *lx ; ++k)
{
tmp_int = 1 + *lx;
w = spwndo(type, &tmp_int, &k);
x[k] *= (float) w;
*tsv += (float) (w * w);
}
*error = 0;
return;
}
tmp_int = *n / 2;
spfftc(x, &tmp_int, &neg_i1);
return;
}
mr = 0;
mr = mr % l + l;
if (mr > m)
{
t.r = x[m].r;
t.i = x[m].i;
x[m].r = x[mr].r;
x[m].i = x[mr].i;
x[mr].r = t.r;
x[mr].i = t.i;
}
}
l = 1;
tmp_int = l * 2;
complex_exp(&tmp_complex, &tmp);
return;
}
#ifndef KR
void r_cnjg(complex *r, complex *z)
#else
void r_cnjg(r, z)
complex *r, *z;
#endif
{
r->r = z->r;
r->i = -z->i;
}
ret_val = 1.0;
switch (*type)
{
break;
case 2:
l = (*n - 2) / 10;
if (*k <= l)
{
ret_val = 0.5 * (1.0 - cos((double) *k * pi
/ ((double) l + 1.0)));
}
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
return(ret_val);
}