ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
FFT.tpp
Go to the documentation of this file.
1#pragma once
2
3template<int fftSize>
4constexpr int FFT<fftSize>::CalculateBits(int size, int count) {
5 return (size <= 1) ? count : CalculateBits(size / 2, count + 1);
6}
7
8template<int fftSize>
9void FFT<fftSize>::BitReverseOrder(float* data) {
10 for (int i = 0; i < fftSize; ++i) {
11 int j = ReverseBits(i);
12 if (i < j) {//Swap the i and j elements
13 Swap(&data[2 * i], &data[2 * j]);//Swap real part
14 Swap(&data[2 * i + 1], &data[2 * j + 1]);//Swap imaginary part
15 }
16 }
17}
18
19template<int fftSize>
20int FFT<fftSize>::ReverseBits(int num) {
21 int reversed = 0;
22 for (int i = 0; i < bitCount; i++) {
23 if (num & (1 << i)) {
24 reversed |= 1 << ((bitCount - 1) - i);
25 }
26 }
27 return reversed;
28}
29
30template<int fftSize>
31void FFT<fftSize>::Swap(float* a, float* b) {
32 float temp = *a;
33 *a = *b;
34 *b = temp;
35}
36
37template<int fftSize>
38void FFT<fftSize>::Radix2FFT(float* data){
39 BitReverseOrder(data);//Bit reversal reordering
40
41 for (int s = 1; s <= log2(fftSize); ++s) {// FFT computation
42 int m = 1 << s; //2 power s
43 int m2 = m >> 1; //m2 = m/2 - bit shift
44 float wReal = 1.0;
45 float wImag = 0.0;
46 float wmReal = cosf(Mathematics::MPI / m2);
47 float wmImag = -sinf(Mathematics::MPI / m2);
48
49 for (int j = 0; j < m2; ++j) {
50 for (int k = j; k < fftSize; k += m) {
51 int t = k + m2;
52 float tr = wReal * data[2 * t] - wImag * data[2 * t + 1];
53 float ti = wReal * data[2 * t + 1] + wImag * data[2 * t];
54
55 data[2 * t] = data[2 * k] - tr;
56 data[2 * t + 1] = data[2 * k + 1] - ti;
57 data[2 * k] += tr;
58 data[2 * k + 1] += ti;
59 }
60
61 float tmpReal = wReal;
62
63 wReal = wReal * wmReal - wImag * wmImag;
64 wImag = tmpReal * wmImag + wImag * wmReal;
65 }
66 }
67}
68
69template<int fftSize>
70void FFT<fftSize>::ComplexMagnitude(float* complexData, float* magnitude){
71 for (int i = 0; i < fftSize; ++i) {
72 float real = complexData[2 * i];//Real part
73 float imag = complexData[2 * i + 1];//Imaginary part
74
75 magnitude[i] = sqrt(real * real + imag * imag);
76 }
77}