diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d8fe4fa
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/.project
diff --git a/Examples/FFT_01/FFT_01.pde b/Examples/FFT_01/FFT_01.pde
new file mode 100644
index 0000000..51404c8
--- /dev/null
+++ b/Examples/FFT_01/FFT_01.pde
@@ -0,0 +1,90 @@
+/*
+
+ Example of use of the FFT libray
+ Copyright (C) 2011 Didier Longueville
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+*/
+
+#include "PlainFFT.h"
+
+PlainFFT FFT = PlainFFT(); /* Create FFT object */
+/*
+These values can be changed in order to evaluate the functions
+*/
+const uint16_t samples = 64;
+double signalFrequency = 1000;
+double samplingFrequency = 5000;
+uint8_t signalIntensity = 100;
+/*
+These are the input and output vectors
+Input vectors receive computed results from FFT
+*/
+double vReal[samples];
+double vImag[samples];
+
+#define SCL_INDEX 0x00
+#define SCL_TIME 0x01
+#define SCL_FREQUENCY 0x02
+
+void setup(){
+ Serial.begin(115200);
+ Serial.println("Ready");
+}
+
+void loop()
+{
+ /* Build raw data */
+ double cycles = (((samples-1) * signalFrequency) / samplingFrequency);
+ for (uint8_t i = 0; i < samples; i++) {
+ vReal[i] = uint8_t((signalIntensity * (sin((i * (6.2831 * cycles)) / samples) + 1.0)) / 2.0);
+ }
+ PrintVector(vReal, samples, SCL_TIME);
+ FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); /* Weigh data */
+ PrintVector(vReal, samples, SCL_TIME);
+ FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
+ PrintVector(vReal, samples, SCL_INDEX);
+ PrintVector(vImag, samples, SCL_INDEX);
+ FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
+ PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);
+ double x = FFT.MajorPeak(vReal, samples, samplingFrequency);
+ Serial.println(x, 6);
+ while(1); /* Run Once */
+ // delay(2000); /* Repeat after delay */
+}
+
+void PrintVector(double *vData, uint8_t bufferSize, uint8_t scaleType)
+{
+ for (uint16_t i = 0; i < bufferSize; i++) {
+ double abscissa;
+ /* Print abscissa value */
+ switch (scaleType) {
+ case SCL_INDEX:
+ abscissa = (i * 1.0);
+ break;
+ case SCL_TIME:
+ abscissa = ((i * 1.0) / samplingFrequency);
+ break;
+ case SCL_FREQUENCY:
+ abscissa = ((i * 1.0 * samplingFrequency) / samples);
+ break;
+ }
+ Serial.print(abscissa, 6);
+ Serial.print(" ");
+ Serial.print(vData[i], 4);
+ Serial.println();
+ }
+ Serial.println();
+}
\ No newline at end of file
diff --git a/PlainFFT.cpp b/PlainFFT.cpp
new file mode 100644
index 0000000..4153d3c
--- /dev/null
+++ b/PlainFFT.cpp
@@ -0,0 +1,181 @@
+/*
+
+ FFT libray
+ Copyright (C) 2010 Didier Longueville
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+*/
+
+#include "PlainFFT.h"
+
+#define twoPi 6.28318531
+#define fourPi 12.56637061
+
+PlainFFT::PlainFFT(void)
+{
+/* Constructor */
+}
+
+PlainFFT::~PlainFFT(void)
+{
+/* Destructor */
+}
+
+uint8_t PlainFFT::Revision(void)
+{
+ return(FFT_LIB_REV);
+}
+
+void PlainFFT::Compute(double *vReal, double *vImag, uint16_t samples, uint8_t dir)
+{
+/* Computes in-place complex-to-complex FFT */
+ /* Reverse bits */
+ uint16_t j = 0;
+ for (uint16_t i = 0; i < (samples - 1); i++) {
+ if (i < j) {
+ Swap(&vReal[i], &vReal[j]);
+ Swap(&vImag[i], &vImag[j]);
+ }
+ uint16_t k = (samples >> 1);
+ while (k <= j) {
+ j -= k;
+ k >>= 1;
+ }
+ j += k;
+ }
+ /* Compute the FFT */
+ double c1 = -1.0;
+ double c2 = 0.0;
+ uint8_t l2 = 1;
+ for (uint8_t l = 0; (l < Exponent(samples)); l++) {
+ uint8_t l1 = l2;
+ l2 <<= 1;
+ double u1 = 1.0;
+ double u2 = 0.0;
+ for (j = 0; j < l1; j++) {
+ for (uint16_t i = j; i < samples; i += l2) {
+ uint16_t i1 = i + l1;
+ double t1 = u1 * vReal[i1] - u2 * vImag[i1];
+ double t2 = u1 * vImag[i1] + u2 * vReal[i1];
+ vReal[i1] = vReal[i] - t1;
+ vImag[i1] = vImag[i] - t2;
+ vReal[i] += t1;
+ vImag[i] += t2;
+ }
+ double z = ((u1 * c1) - (u2 * c2));
+ u2 = ((u1 * c2) + (u2 * c1));
+ u1 = z;
+ }
+ c2 = sqrt((1.0 - c1) / 2.0);
+ if (dir == FFT_FORWARD) {
+ c2 = -c2;
+ }
+ c1 = sqrt((1.0 + c1) / 2.0);
+ }
+ /* Scaling for reverse transform */
+ if (dir != FFT_FORWARD) {
+ for (uint16_t i = 0; i < samples; i++) {
+ vReal[i] /= samples;
+ vImag[i] /= samples;
+ }
+ }
+}
+
+void PlainFFT::ComplexToMagnitude(double *vReal, double *vImag, uint16_t samples)
+{
+/* vM is half the size of vReal and vImag */
+ for (uint8_t i = 0; i < samples; i++) {
+ vReal[i] = sqrt(sq(vReal[i]) + sq(vImag[i]));
+ }
+}
+
+void PlainFFT::Windowing(double *vData, uint16_t samples, uint8_t windowType, uint8_t dir)
+{
+/* Weighing factors are computed once before multiple use of FFT */
+/* The weighing function is symetric; half the weighs are recorded */
+ double samplesMinusOne = (double(samples) - 1.0);
+ for (uint16_t i = 0; i < (samples >> 1); i++) {
+ double indexMinusOne = double(i);
+ double ratio = (indexMinusOne / samplesMinusOne);
+ double weighingFactor = 1.0;
+ /* Compute and record weighting factor */
+ switch (windowType) {
+ case FFT_WIN_TYP_RECTANGLE: /* rectangle (box car) */
+ weighingFactor = 1.0;
+ break;
+ case FFT_WIN_TYP_HAMMING: /* hamming */
+ weighingFactor = 0.54 - (0.46 * cos(twoPi * ratio));
+ break;
+ case FFT_WIN_TYP_HANN: /* hann */
+ weighingFactor = 0.54 * (1.0 - cos(twoPi * ratio));
+ break;
+ case FFT_WIN_TYP_TRIANGLE: /* triangle (Bartlett) */
+ weighingFactor = 1.0 - ((2.0 * abs(indexMinusOne - (samplesMinusOne / 2.0))) / samplesMinusOne);
+ break;
+ case FFT_WIN_TYP_BLACKMAN: /* blackmann */
+ weighingFactor = 0.42323 - (0.49755 * (cos(twoPi * ratio))) + (0.07922 * (cos(fourPi * ratio)));
+ break;
+ case FFT_WIN_TYP_FLT_TOP: /* flat top */
+ weighingFactor = 0.2810639 - (0.5208972 * cos(twoPi * ratio)) + (0.1980399 * cos(fourPi * ratio));
+ break;
+ case FFT_WIN_TYP_WELCH: /* welch */
+ weighingFactor = 1.0 - sq((indexMinusOne - samplesMinusOne / 2.0) / (samplesMinusOne / 2.0));
+ break;
+ }
+ if (dir == FFT_FORWARD) {
+ vData[i] *= weighingFactor;
+ vData[samples - (i + 1)] *= weighingFactor;
+ }
+ else {
+ vData[i] /= weighingFactor;
+ vData[samples - (i + 1)] /= weighingFactor;
+ }
+ }
+}
+
+double PlainFFT::MajorPeak(double *vD, uint16_t samples, double samplingFrequency)
+{
+ double maxY = 0;
+ uint16_t IndexOfMaxY = 0;
+ for (uint16_t i = 1; i < ((samples >> 1) - 1); i++) {
+ if ((vD[i-1] < vD[i]) && (vD[i] > vD[i+1])) {
+ if (vD[i] > maxY) {
+ maxY = vD[i];
+ IndexOfMaxY = i;
+ }
+ }
+ }
+ double delta = 0.5 * ((vD[IndexOfMaxY-1] - vD[IndexOfMaxY+1]) / (vD[IndexOfMaxY-1] - (2.0 * vD[IndexOfMaxY]) + vD[IndexOfMaxY+1]));
+ double interpolatedX = ((IndexOfMaxY + delta) * samplingFrequency) / (samples-1);
+ /* retuned value: interpolated frequency peak apex */
+ return(interpolatedX);
+}
+
+/* Private functions */
+
+void PlainFFT::Swap(double *x, double *y)
+{
+ double temp = *x;
+ *x = *y;
+ *y = temp;
+}
+
+uint8_t PlainFFT::Exponent(uint16_t value)
+{
+ /* Computes the Exponent of a powered 2 value */
+ uint8_t result = 0;
+ while (((value >> result) & 1) != 1) result++;
+ return(result);
+}
\ No newline at end of file
diff --git a/PlainFFT.h b/PlainFFT.h
new file mode 100644
index 0000000..5a49570
--- /dev/null
+++ b/PlainFFT.h
@@ -0,0 +1,59 @@
+/*
+
+ FFT libray
+ Copyright (C) 2010 Didier Longueville
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+*/
+
+#ifndef PlainFFT_h /* Prevent loading library twice */
+#define PlainFFT_h
+
+#include "WProgram.h" /* This is where the standard Arduino code lies */
+
+#define FFT_LIB_REV 0x02
+/* Custom constants */
+#define FFT_FORWARD 0x01
+#define FFT_REVERSE 0x00
+/* Windowing type */
+#define FFT_WIN_TYP_RECTANGLE 0x00 /* rectangle (Box car) */
+#define FFT_WIN_TYP_HAMMING 0x01 /* hamming */
+#define FFT_WIN_TYP_HANN 0x02 /* hann */
+#define FFT_WIN_TYP_TRIANGLE 0x03 /* triangle (Bartlett) */
+#define FFT_WIN_TYP_BLACKMAN 0x04 /* blackmann */
+#define FFT_WIN_TYP_FLT_TOP 0x05 /* flat top */
+#define FFT_WIN_TYP_WELCH 0x06 /* welch */
+
+class PlainFFT {
+public:
+ /* Constructor */
+ PlainFFT(void);
+ /* Destructor */
+ ~PlainFFT(void);
+ /* Functions */
+ void ComplexToMagnitude(double *vReal, double *vImag, uint16_t samples);
+ void Compute(double *vReal, double *vImag, uint16_t samples, uint8_t dir);
+ double MajorPeak(double *vD, uint16_t samples, double samplingFrequency);
+ uint8_t Revision(void);
+ void Windowing(double *vData, uint16_t samples, uint8_t windowType, uint8_t dir);
+
+private:
+ /* Functions */
+ uint8_t Exponent(uint16_t value);
+ void Swap(double *x, double *y);
+
+};
+
+#endif
diff --git a/README.md b/README.md
index 7251692..cad7c21 100644
--- a/README.md
+++ b/README.md
@@ -4,3 +4,33 @@ arduinoFFT
Fast Fourier Transform for Arduino
This is a fork from https://code.google.com/p/makefurt/ which has been abandoned since 2011.
+
+This is a C++ library for Arduino for computing FFT.
+Tested on Arduino 0022 Alpha.
+
+Installation
+--------------------------------------------------------------------------------
+
+To install this library, just place this entire folder as a subfolder in your
+
+
+When installed, this library should look like:
+
+Arduino\libraries\PlainFTT (this library's folder)
+Arduino\libraries\PlainFTT\PlainFTT.cpp (the library implementation file, uses 32 bits floats vectors)
+Arduino\libraries\PlainFTT\PlainFTT.h (the library description file, uses 32 bits floats vectors)
+Arduino\libraries\PlainFTT\PlainFTT_INT.cpp (the library implementation file, experimental signed 16 bits vectors)
+Arduino\libraries\PlainFTT\PlainFTT_INT.h (the library description file, experimental signed 16 bits vectors)
+Arduino\libraries\PlainFTT\keywords.txt (the syntax coloring file)
+Arduino\libraries\PlainFTT\examples (the examples in the "open" menu)
+Arduino\libraries\PlainFTT\readme.txt (this file)
+
+Building
+--------------------------------------------------------------------------------
+
+After this library is installed, you just have to start the Arduino application.
+You may see a few warning messages as it's built.
+
+To use this library in a sketch, go to the Sketch | Import Library menu and
+select PlainFTT. This will add a corresponding line to the top of your sketch:
+#include (or #include
diff --git a/keywords.txt b/keywords.txt
new file mode 100644
index 0000000..93e62ae
--- /dev/null
+++ b/keywords.txt
@@ -0,0 +1,21 @@
+#######################################
+# Syntax Coloring Map For PlainFFT
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+PlainFFT KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+complexToMagnitude KEYWORD2
+compute KEYWORD2
+windowing KEYWORD2
+exponent KEYWORD2
+swap KEYWORD2
+revision KEYWORD2
+majorPeak KEYWORD2
\ No newline at end of file