-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfft.h
120 lines (96 loc) · 2.53 KB
/
fft.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
* fft.h
*
* Created on: 26.09.2012
* Author: mse
*/
#ifndef FFT_H_
#define FFT_H_
/* fix_fft.c - Fixed-point in-place Fast Fourier Transform */
/*
All data are fixed-point short integers, in which -32768
to +32768 represent -1.0 to +1.0 respectively. Integer
arithmetic is used for speed, instead of the more natural
floating-point.
Written by: Tom Roberts 11/8/89
Made portable: Malcolm Slaney 12/15/94 [email protected]
Enhanced: Dimitrios P. Bouras 14 Jun 2006 [email protected]
Adapted for Arduino: Anatoly Kuzmenko 6 Feb 2011 [email protected]
*/
//**************************************************************************************************
#include "sinus.h"
#define LOG2_N_WAVE 10 /* log2(N_WAVE) */
#define FFT_SIZE 64
#define log2FFT 6
#define N (2 * FFT_SIZE)
#define log2N (log2FFT + 1)
//**************************************************************************************************
int fix_fft(int fr[], int fi[], int m )
{
int mr, nn, i, j, l, k, istep, n, scale, shift;
int qr, qi, tr, ti, wr, wi;
n = 1 << m;
/* max FFT size = N_WAVE */
if (n > N_WAVE)
return -1;
mr = 0;
nn = n - 1;
scale = 0;
/* decimation in time - re-order data */
for (m=1; m<=nn; ++m) {
l = n;
do {
l >>= 1;
}
while (mr+l > nn);
mr = (mr & (l-1)) + l;
if (mr <= m)
continue;
tr = fr[m];
fr[m] = fr[mr];
fr[mr] = tr;
ti = fi[m];
fi[m] = fi[mr];
fi[mr] = ti;
}
l = 1;
k = LOG2_N_WAVE-1;
while (l < n) {
shift = 1;
istep = l << 1;
for (m=0; m<l; ++m) {
j = m << k;
/* 0 <= j < N_WAVE/2 */
wr = pgm_read_word(&Sinewave[j+N_WAVE/4]);
wi = -pgm_read_word(&Sinewave[j]);
wr >>= 1;
wi >>= 1;
for (i=m; i<n; i+=istep) {
j = i + l;
tr = ((long)wr*(long)fr[j] - (long)wi*(long)fi[j])>>15;
ti = ((long)wr*(long)fi[j] + (long)wi*(long)fr[j])>>15;
qr = fr[i];
qi = fi[i];
qr >>= 1;
qi >>= 1;
fr[j] = qr - tr;
fi[j] = qi - ti;
fr[i] = qr + tr;
fi[i] = qi + ti;
}
}
--k;
l = istep;
}
return scale;
}
//Performing FFT, getting fx[] array, where each element represents
//frequency bin with width 65 Hz.
int fix_fftr(int f[], int m )
{
int Nt = 1<<(m-1), scale = 0;
int *fr=f, *fi=&f[Nt];
scale = fix_fft(fi, fr, m-1 );
return scale;
}
#endif /* FFT_H_ */