Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Diff: FFT.cpp
- Revision:
- 1:099f1a4c5fc8
- Parent:
- 0:8c128e047ec9
--- a/FFT.cpp Tue Mar 28 08:48:23 2017 +0000
+++ b/FFT.cpp Wed Mar 29 08:42:31 2017 +0000
@@ -1,1 +1,132 @@
-#include "FFT.h"
\ No newline at end of file
+#include "FFT.h"
+
+
+// Calculates and subtracts the signal mean
+void subMean(float* data, int datalength){
+ float mean = 0;
+ float total = 0;
+ for (int i = 0; i < datalength; i++)
+ total += data[i]/datalength;
+ for (int i = 0; i < datalength; i++)
+ data[i] = data[i] - mean;
+}
+
+void reverseCooleyTukeyRadix2(float* data, complex_num* dataout, int datalength){
+
+ complex_num fftbuffer[256];
+ complex_num twiddlebuffer;
+
+ complex_num minusone;
+ minusone.real = -1;
+ minusone.imaginary = 0;
+
+ // copy iput to output first
+ for (int i = 0; i < datalength; i++){
+ dataout[i].real = data[i];
+ dataout[i].imaginary = 0;
+ }
+
+ for (int stage = 8; stage > -1; stage--){
+
+ unsigned int step = 1<<(stage+1);
+
+ for (unsigned int i = 0; i < 512; i = i+step){ // Crack it up in parts, i.e. for stage0 -> 512, stage1 -> 256 , 2>128, 3>64, 4>32, 5>16, 6>8, 7>4, 8>2, 9>1 --> 1024/2^stage OR IN STEPS: stage0 -> 2, stage1 -> 4, 2>8, 3>16, 4,32, 5>64, ......... 9>512 --> 1024 - 1024/2^stage+1
+ // Buffer the first 'half' of the thing, which is the first half step
+ for (unsigned int k = 0; k < step / 2; k++){
+ fftbuffer[k].real = dataout[i+k].real;
+ fftbuffer[k].imaginary = dataout[i+k].imaginary;
+ }
+
+ // Apply twiddle factors to the seconds half (half step) depending on stage and numbering
+ for (unsigned int k = 0; k < step / 2; k++){
+ // Read in the correct twiddle factor
+ // Twiddle factor is recalculated with k*(1024 / 2^stage+1) which can be recalculated to 1<<
+ twiddlebuffer.imaginary = twiddleLookupTable_Imaginary[k * (1<<(9-stage))];
+ twiddlebuffer.real = twiddleLookupTable_Real[k * (1 << (9 - stage))];
+
+ dataout[i + k + step / 2] = complex_multiply(dataout[i + k + step / 2], twiddlebuffer);
+ }
+
+ // Recalculate the first half by addition of the first and recalculated half
+ for (unsigned int k = 0; k < step / 2; k++)
+ dataout[i + k] = complex_add(dataout[i+k], dataout[i+k+step/2]);
+
+
+ // Multiply the second half with minus 1
+ for (unsigned int k = 0; k < step / 2; k++)
+ dataout[i + step / 2 + k] = complex_multiply(dataout[i + step/2+k], minusone);
+
+ // Add the buffered old values, with the new second half values
+ for (unsigned int k = 0; k < step / 2; k++)
+ dataout[i + step / 2 + k] = complex_add(dataout[i + step/2 + k], fftbuffer[k]);
+ }
+ }
+}
+
+void cooleyTukeyBack (float* dataout, complex_num* datain, int datalength){
+ complex_num fftbuffer[256];
+ complex_num twiddlebuffer;
+
+ complex_num minusone;
+ minusone.real = -1;
+ minusone.imaginary = 0;
+
+ for (int stage = 0; stage < 9; stage++){
+
+ unsigned int step = 1<<(stage+1);
+
+ for (unsigned int i = 0; i < 512; i = i+step){ // Crack it up in parts, i.e. for stage0 -> 512, stage1 -> 256 , 2>128, 3>64, 4>32, 5>16, 6>8, 7>4, 8>2, 9>1 --> 1024/2^stage OR IN STEPS: stage0 -> 2, stage1 -> 4, 2>8, 3>16, 4,32, 5>64, ......... 9>512 --> 1024 - 1024/2^stage+1
+ // Buffer the first 'half' of the thing, which is the first half step
+ for (unsigned int k = 0; k < step / 2; k++){
+ fftbuffer[k].real = datain[i+k].real;
+ fftbuffer[k].imaginary = datain[i+k].imaginary;
+ }
+
+ // Apply twiddle factors to the seconds half (half step) depending on stage and numbering
+ for (unsigned int k = 0; k < step / 2; k++){
+ // Read in the correct twiddle factor
+ // Twiddle factor is recalculated with N-k*(1024 / 2^stage+1) which can be recalculated to 1<<
+ twiddlebuffer.imaginary = twiddleLookupTable_Imaginary[512-(k * (1<<(9-stage)))];
+ twiddlebuffer.real = twiddleLookupTable_Real[512-(k * (1 << (9 - stage)))];
+
+ datain[i + k + step / 2] = complex_multiply(datain[i + k + step / 2], twiddlebuffer);
+ }
+
+ // Recalculate the first half by addition of the first and recalculated half
+ for (unsigned int k = 0; k < step / 2; k++)
+ datain[i + k] = complex_add(datain[i+k], datain[i+k+step/2]);
+
+
+ // Multiply the second half with minus 1
+ for (unsigned int k = 0; k < step / 2; k++)
+ datain[i + step / 2 + k] = complex_multiply(datain[i + step/2+k], minusone);
+
+ // Add the buffered old values, with the new second half values
+ for (unsigned int k = 0; k < step / 2; k++)
+ datain[i + step / 2 + k] = complex_add(datain[i + step/2 + k], fftbuffer[k]);
+ }
+ }
+ //first convert complex data back to magnitude data then divide by 1/N
+ for (int i = 0; i < 512; i++)
+ dataout[i] = (complex_magnitude(datain[i])/512);
+}
+
+void equalizer(complex_num* data){
+
+}
+
+void performEqualizer(float* datain, float* dataout, complex_num* freqdata, int datalength){
+ if (datalength == 512){
+ // - Calculating and substracting the mean -
+ subMean(datain, datalength);
+ // - Applying a hanning window - N multiplications
+ applyHanningTable(datain, datalength);
+ // It then applies a radix-2 Cooley Tukey FFT to create a fourier transform
+ reverseCooleyTukeyRadix2(datain, freqdata, datalength);
+ // It gets equalized
+ equalizer(freqdata);
+ // back to time domain
+ cooleyTukeyBack(dataout, freqdata, datalength);
+ }
+
+}
\ No newline at end of file