Porównaj commity

...

71 Commity

Autor SHA1 Wiadomość Data
Enrique Condes 0da88512f9
Merge pull request #95 from kosme/develop
Version 2.0.2. Patch for issues 92/93
2024-04-18 17:13:59 +08:00
Enrique Condes 04fbc35bda Version 2.0.2. Patch for issue 92/93 2024-04-18 17:12:43 +08:00
Enrique Condes 3be858dd29
Merge pull request #94 from kosme/develop
Reapply PR 83 and fix typos in examples
2024-04-15 22:24:43 +08:00
Enrique Condes 1936a46549 Reapply PR 83 and fix typos in examples 2024-04-15 22:21:59 +08:00
Enrique Condes 3d17cac4c9
Merge pull request #91 from kosme/develop
Version 2.0 from develop branch
2024-03-06 14:29:10 +08:00
Enrique Condes 909240fe79 Merge branch 'develop' into master 2024-03-06 14:27:41 +08:00
Enrique Condes a9f64fb886 Version 2.0 2024-03-06 13:56:17 +08:00
Enrique Condes bb90780ace
Merge pull request #88 from kosme/v1.6.2
Fix bug on synthetic data generation
2023-12-29 11:07:30 +08:00
Enrique Condes c7845ab60e Fix bug on synthetic data generation 2023-12-29 11:00:17 +08:00
Enrique Condes b0e4c69bcb Fix issue 84 2023-07-25 23:39:34 +08:00
Enrique Condes 419d7b044e
Merge pull request #83 from FintasticMan/customisable_sqrt
Make the sqrt_internal macro customisable
2023-05-26 14:55:19 -06:00
Finlay Davidson 5c652cdc95 Make the sqrt_internal macro customisable 2023-04-03 22:00:36 +02:00
Enrique Condes 78ec583c60
Merge pull request #81 from BjornTheProgrammer/master
Update Examples and Documentation to Reflect Real Status
2023-03-20 16:53:25 -06:00
Bjorn f9d6fa7dae Updated Documentation to Reflect Actual Methods 2023-03-17 23:41:46 -07:00
Bjorn fa12c7b8f0 Updated Examples to use Non-Deprecated Methods
Updated the examples FFT_01, FFT_02, FFT_03, FFT_04, and FFT_05.
2023-03-17 23:31:04 -07:00
kosme 94453e54ac Bump to version 1.6 2023-03-09 22:28:40 -06:00
Enrique Condes e5e4c745c1
Delete lookup-table.ods 2022-09-26 18:32:38 -05:00
Enrique Condes 81d62e1002
Delete arduinoFFT.cpp 2022-09-26 18:32:13 -05:00
Enrique Condes 32723c635c Merge branch 'develop' of github.com:kosme/arduinoFFT into develop 2022-09-26 17:14:23 -05:00
Enrique Condes 3a637a12f6 Merge branch 'develop' of github.com:kosme/arduinoFFT into develop 2022-09-26 17:13:00 -05:00
Enrique Condes 0565c8824f Merge branch 'develop' of github.com:kosme/arduinoFFT into develop 2022-09-26 17:11:41 -05:00
Enrique Condes 8c925a74fd Correctly detect ESP32 boards 2022-09-26 17:07:55 -05:00
Enrique Condes 11b157184e Correctly detect ESP32 boards 2022-09-26 16:39:19 -05:00
Enrique Condes 11b7937333
Merge pull request #71 from slaff/fix/spelling
Fixed small spelling mistakes.
2021-12-09 14:49:57 -06:00
Slavey Karadzhov dec237ab14 Fixed small spelling mistakes. 2021-12-09 12:42:40 +01:00
Enrique Condes bd164d1c3d
Merge pull request #68 from blaz-r/develop
Reordered variables in class, to fix -Werror=reorder
2021-11-27 11:03:15 -06:00
Enrique Condes 5f622f7c0c
Merge branch 'develop' into develop 2021-11-27 11:03:05 -06:00
Enrique Condes e7357ccbaf
Merge pull request #59 from drzony/reordering-fix
Fixed compilation with -Wextra
2021-11-27 10:57:18 -06:00
Enrique Condes cd339adae2
Merge pull request #70 from ivankravets/patch-1
Declare header files for PlatformIO
2021-11-27 10:56:35 -06:00
Ivan Kravets e39f2f12a8
Declare header files for PlatformIO 2021-11-19 12:16:53 +02:00
blaz-r 3fce8acb88 Reordered variables in class to fix -Werror=reorder 2021-09-13 08:59:30 +02:00
Enrique Condes bb99065f9a
Merge pull request #64 from Phatcat/Parabola
Improve MajorPeak with parabola
2021-02-05 19:04:38 -06:00
MarScaper 54c383a62f Improve MajorPeak with parabola
I would like to submit you an improvement in frequency estimation by using a parabola estimation using three points...

https://github.com/kosme/arduinoFFT/issues/41
2021-02-05 17:26:08 +01:00
Drzony 7b107cf490 Fixed compilation with -Wextra 2020-11-06 10:11:51 +01:00
Enrique Condes 566803e9ca Publish version 1.5.6 2020-10-06 15:18:15 -05:00
Enrique Condes b19bdc7b6c Fix to issue 57 2020-10-06 15:08:33 -05:00
Enrique Condes 89defc7588 Merge branch 'master' of https://github.com/kosme/arduinoFFT into master 2020-10-06 14:47:29 -05:00
Enrique Condes ee0459d537 Fix for issue 56 2020-10-06 14:47:01 -05:00
Enrique Condes 5eaad08339
Merge pull request #50 from HorstBaerbel/master
Fix compile error on Arduino due to small_type
2020-07-02 09:53:09 -05:00
Enrique Condes 4011ca2749
Merge pull request #49 from pranabendra/master
Fix DCRemoval(): average all samples in time
2020-07-02 09:51:11 -05:00
Bim Overbohm 0a9cd2b425 Fix compile error on Arduino due to small_type 2020-07-01 14:34:07 +02:00
pranabendra b36336c12d Fix DCRemoval(): for all samples in time 2020-06-07 20:51:03 +05:30
Bim Overbohm 35ea7e243f Fix README anchor 2020-02-22 13:39:04 +01:00
Bim Overbohm 4a36bd2453 Add setArrays() function because of issue #32. Add API migration info to README and improve README. 2020-02-22 13:35:09 +01:00
Bim Overbohm 3e73c9884b Use better sqrtf approximation (precise, no divisions) 2020-02-22 12:38:26 +01:00
Bim Overbohm 6df8d2d70f Add missing include if compiled from Visual Studio Code + Arduino Extension 2020-02-20 20:54:34 +01:00
Bim Overbohm 49bc726738 Add windowing compensation factors 2020-02-19 18:06:11 +01:00
Bim Overbohm 08e9288cc9 Fix example FFT_02 2020-02-19 17:28:01 +01:00
Bim Overbohm cb33149c17 Remove deprecated functions, templatize, Speedup 2020-02-19 17:15:49 +01:00
Enrique Condes 8459c48952 Lookup table for c1 and c2 2020-01-27 14:27:39 +08:00
Enrique Condes 852d7466ab Lookup table for c1 and c2 2020-01-27 14:27:27 +08:00
Enrique Condes bb4769a44f Latest code in release 2019-04-30 16:31:43 +08:00
Enrique Condes 4019b12c9b New MajorPeak fucntion that returns peak magnitude 2019-01-03 00:32:15 +08:00
Enrique Condes d6d1aca0c9
Merge pull request #24 from Dantali0n/master
New function to perform DC removal from sample data
2018-11-25 23:48:28 +08:00
Dantali0n ae724e6c37 remove undefined function 2018-11-24 11:47:01 +01:00
Dantali0n efc53f9f60 Add DC removal function 2018-11-24 11:42:59 +01:00
Enrique Condes e79104dbc0
Merge pull request #22 from Dantali0n/master
Add nuttall & blackman complimentary windowing
2018-10-26 22:40:43 +08:00
Dantali0n 68e59c2e61 Add nuttall & blackman complimentary windowing
Add functions for nuttall, blackman-nuttall and blackman-harris windowing
2018-10-26 12:24:13 +02:00
Enrique Condes a060c2f7d1
Merge pull request #21 from edgar-bonet/fix-rollover
FFT_03.ino: fix micros() rollover issue and sampling frequency
2018-09-19 18:49:30 +08:00
Edgar Bonet c564008306 Ensure accurate sampling frequency in FFT_03.ino 2018-09-19 12:32:05 +02:00
Edgar Bonet 92f4066a72 Fix micros() rollover issue in FFT_03.ino 2018-09-19 12:31:52 +02:00
Enrique Condes d8c22a897e Version 1.4
- Descriptor for Plaformio
- New API with simpled functions
- Fixes on rare bugs
2018-02-11 04:02:53 +08:00
Enrique Condes de7c8e447c Minor fix on examples 2018-02-11 03:59:45 +08:00
Enrique Condes e28c4e91cb Fix separator issue 2018-02-11 03:21:28 +08:00
Enrique Condes 0b3271b489 Remove new printing methods on examples 2018-02-11 03:21:10 +08:00
Enrique Condes e1831a9bdd Spectrum Plot example 2018-02-07 16:04:17 +08:00
Enrique Condes e7edcefebb Improved example code. Thanks to Ragnar Ranøyen 2018-02-07 16:03:41 +08:00
Enrique Condes c239231546 Examples using the new printing functions 2018-02-01 21:04:41 +08:00
Enrique Condes 934ff09b95 Add clearer printing and ploting functions 2018-02-01 21:02:38 +08:00
kosme 7ace8062ea Update to v1.3 Now supporting mbed boards 2017-12-06 02:37:25 +08:00
Enrique Condes bb07a0fbc5 Create change log to document changes between versions. 2017-09-04 10:35:26 -05:00
16 zmienionych plików z 1201 dodań i 341 usunięć

1
.gitignore vendored
Wyświetl plik

@ -1,2 +1,3 @@
/.project
/sync.ffs_db
*.*bak

Wyświetl plik

@ -1,7 +1,9 @@
/*
Example of use of the FFT libray
Copyright (C) 2014 Enrique Condes
Example of use of the FFT library
Copyright (C) 2014 Enrique Condes
Copyright (C) 2020 Bim Overbohm (template, speed improvements)
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
@ -30,7 +32,6 @@
#include "arduinoFFT.h"
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */
/*
These values can be changed in order to evaluate the functions
*/
@ -38,6 +39,7 @@ const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2
const double signalFrequency = 1000;
const double samplingFrequency = 5000;
const uint8_t amplitude = 100;
/*
These are the input and output vectors
Input vectors receive computed results from FFT
@ -45,41 +47,46 @@ Input vectors receive computed results from FFT
double vReal[samples];
double vImag[samples];
/* Create FFT object */
ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency);
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03
void setup()
{
Serial.begin(115200);
while(!Serial);
Serial.println("Ready");
}
void loop()
{
/* Build raw data */
double cycles = (((samples-1) * signalFrequency) / samplingFrequency); //Number of signal cycles that the sampling will read
double ratio = twoPi * signalFrequency / samplingFrequency; // Fraction of a complete cycle stored at each sample (in radians)
for (uint16_t i = 0; i < samples; i++)
{
vReal[i] = int8_t((amplitude * (sin((i * (twoPi * cycles)) / samples))) / 2.0);/* Build data with positive and negative values*/
//vReal[i] = uint8_t((amplitude * (sin((i * (twoPi * cycles)) / samples) + 1.0)) / 2.0);/* Build data displaced on the Y axis to include only positive values*/
vReal[i] = int8_t(amplitude * sin(i * ratio) / 2.0);/* Build data with positive and negative values*/
//vReal[i] = uint8_t((amplitude * (sin(i * ratio) + 1.0)) / 2.0);/* Build data displaced on the Y axis to include only positive values*/
vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
}
/* Print the results of the simulated sampling according to time */
Serial.println("Data:");
PrintVector(vReal, samples, SCL_TIME);
FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); /* Weigh data */
FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */
Serial.println("Weighed data:");
PrintVector(vReal, samples, SCL_TIME);
FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
FFT.compute(FFTDirection::Forward); /* Compute FFT */
Serial.println("Computed Real values:");
PrintVector(vReal, samples, SCL_INDEX);
Serial.println("Computed Imaginary values:");
PrintVector(vImag, samples, SCL_INDEX);
FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
FFT.complexToMagnitude(); /* Compute magnitudes */
Serial.println("Computed magnitudes:");
PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);
double x = FFT.MajorPeak(vReal, samples, samplingFrequency);
double x = FFT.majorPeak();
Serial.println(x, 6);
while(1); /* Run Once */
// delay(2000); /* Repeat after delay */
@ -104,9 +111,10 @@ void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType)
break;
}
Serial.print(abscissa, 6);
if(scaleType==SCL_FREQUENCY)
Serial.print("Hz");
Serial.print(" ");
Serial.print(vData[i], 4);
Serial.println();
Serial.println(vData[i], 4);
}
Serial.println();
}

Wyświetl plik

@ -1,10 +1,12 @@
/*
Example of use of the FFT libray to compute FFT for several signals over a range of frequencies.
The exponent is calculated once before the excecution since it is a constant.
This saves resources during the excecution of the sketch and reduces the compiled size.
The sketch shows the time that the computing is taking.
Copyright (C) 2014 Enrique Condes
Example of use of the FFT library to compute FFT for several signals over a range of frequencies.
The exponent is calculated once before the execution since it is a constant.
This saves resources during the execution of the sketch and reduces the compiled size.
The sketch shows the time that the computing is taking.
Copyright (C) 2014 Enrique Condes
Copyright (C) 2020 Bim Overbohm (template, speed improvements)
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
@ -23,15 +25,12 @@
#include "arduinoFFT.h"
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */
/*
These values can be changed in order to evaluate the functions
*/
const uint16_t samples = 64;
const double sampling = 40;
const uint8_t amplitude = 4;
uint8_t exponent;
const double startFrequency = 2;
const double stopFrequency = 16.4;
const double step_size = 0.1;
@ -43,17 +42,21 @@ Input vectors receive computed results from FFT
double vReal[samples];
double vImag[samples];
unsigned long time;
/* Create FFT object */
ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, sampling);
unsigned long startTime;
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03
void setup()
{
Serial.begin(115200);
while(!Serial);
Serial.println("Ready");
exponent = FFT.Exponent(samples);
}
void loop()
@ -63,32 +66,32 @@ void loop()
for(double frequency = startFrequency; frequency<=stopFrequency; frequency+=step_size)
{
/* Build raw data */
double cycles = (((samples-1) * frequency) / sampling);
double ratio = twoPi * frequency / sampling; // Fraction of a complete cycle stored at each sample (in radians)
for (uint16_t i = 0; i < samples; i++)
{
vReal[i] = int8_t((amplitude * (sin((i * (twoPi * cycles)) / samples))) / 2.0);
vReal[i] = int8_t(amplitude * sin(i * ratio) / 2.0);/* Build data with positive and negative values*/
vImag[i] = 0; //Reset the imaginary values vector for each new frequency
}
/*Serial.println("Data:");
PrintVector(vReal, samples, SCL_TIME);*/
time=millis();
FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); /* Weigh data */
startTime=millis();
FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */
/*Serial.println("Weighed data:");
PrintVector(vReal, samples, SCL_TIME);*/
FFT.Compute(vReal, vImag, samples, exponent, FFT_FORWARD); /* Compute FFT */
FFT.compute(FFTDirection::Forward); /* Compute FFT */
/*Serial.println("Computed Real values:");
PrintVector(vReal, samples, SCL_INDEX);
Serial.println("Computed Imaginary values:");
PrintVector(vImag, samples, SCL_INDEX);*/
FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
FFT.complexToMagnitude(); /* Compute magnitudes */
/*Serial.println("Computed magnitudes:");
PrintVector(vReal, (samples >> 1), SCL_FREQUENCY); */
double x = FFT.MajorPeak(vReal, samples, sampling);
PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);*/
double x = FFT.majorPeak();
Serial.print(frequency);
Serial.print(": \t\t");
Serial.print(x, 4);
Serial.print("\t\t");
Serial.print(millis()-time);
Serial.print(millis()-startTime);
Serial.println(" ms");
// delay(2000); /* Repeat after delay */
}
@ -105,18 +108,19 @@ void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType)
{
case SCL_INDEX:
abscissa = (i * 1.0);
break;
break;
case SCL_TIME:
abscissa = ((i * 1.0) / sampling);
break;
break;
case SCL_FREQUENCY:
abscissa = ((i * 1.0 * sampling) / samples);
break;
break;
}
Serial.print(abscissa, 6);
if(scaleType==SCL_FREQUENCY)
Serial.print("Hz");
Serial.print(" ");
Serial.print(vData[i], 4);
Serial.println();
Serial.println(vData[i], 4);
}
Serial.println();
}

Wyświetl plik

@ -1,7 +1,9 @@
/*
Example of use of the FFT libray to compute FFT for a signal sampled through the ADC.
Copyright (C) 2017 Enrique Condes
Example of use of the FFT library to compute FFT for a signal sampled through the ADC.
Copyright (C) 2018 Enrique Condés and Ragnar Ranøyen Homb
Copyright (C) 2020 Bim Overbohm (template, speed improvements)
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
@ -20,15 +22,14 @@
#include "arduinoFFT.h"
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */
/*
These values can be changed in order to evaluate the functions
*/
#define CHANNEL A0
const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2
const double samplingFrequency = 200;
unsigned int delayTime = 0;
const double samplingFrequency = 100; //Hz, must be less than 10000 due to ADC
unsigned int sampling_period_us;
unsigned long microseconds;
/*
These are the input and output vectors
@ -37,49 +38,53 @@ Input vectors receive computed results from FFT
double vReal[samples];
double vImag[samples];
/* Create FFT object */
ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency);
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03
void setup()
{
if(samplingFrequency<=1000)
delayTime = 1000/samplingFrequency;
else
delayTime = 1000000/samplingFrequency;
sampling_period_us = round(1000000*(1.0/samplingFrequency));
Serial.begin(115200);
while(!Serial);
Serial.println("Ready");
}
void loop()
{
for(uint16_t i =0;i<samples;i++)
/*SAMPLING*/
microseconds = micros();
for(int i=0; i<samples; i++)
{
vReal[i] = double(analogRead(CHANNEL));
vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
if(samplingFrequency<=1000)
delay(delayTime);
else
delayMicroseconds(delayTime);
vReal[i] = analogRead(CHANNEL);
vImag[i] = 0;
while(micros() - microseconds < sampling_period_us){
//empty loop
}
microseconds += sampling_period_us;
}
/* Print the results of the sampling according to time */
Serial.println("Data:");
PrintVector(vReal, samples, SCL_TIME);
FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); /* Weigh data */
FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */
Serial.println("Weighed data:");
PrintVector(vReal, samples, SCL_TIME);
FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
FFT.compute(FFTDirection::Forward); /* Compute FFT */
Serial.println("Computed Real values:");
PrintVector(vReal, samples, SCL_INDEX);
Serial.println("Computed Imaginary values:");
PrintVector(vImag, samples, SCL_INDEX);
FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
FFT.complexToMagnitude(); /* Compute magnitudes */
Serial.println("Computed magnitudes:");
PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);
double x = FFT.MajorPeak(vReal, samples, samplingFrequency);
Serial.println(x, 6);
double x = FFT.majorPeak();
Serial.println(x, 6); //Print out what frequency is the most dominant.
while(1); /* Run Once */
// delay(2000); /* Repeat after delay */
}
void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType)
@ -101,9 +106,10 @@ void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType)
break;
}
Serial.print(abscissa, 6);
if(scaleType==SCL_FREQUENCY)
Serial.print("Hz");
Serial.print(" ");
Serial.print(vData[i], 4);
Serial.println();
Serial.println(vData[i], 4);
}
Serial.println();
}

Wyświetl plik

@ -0,0 +1,112 @@
/*
Example of use of the FFT library
Copyright (C) 2018 Enrique Condes
Copyright (C) 2020 Bim Overbohm (template, speed improvements)
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 <http://www.gnu.org/licenses/>.
*/
/*
In this example, the Arduino simulates the sampling of a sinusoidal 1000 Hz
signal with an amplitude of 100, sampled at 5000 Hz. Samples are stored
inside the vReal array. The samples are windowed according to Hamming
function. The FFT is computed using the windowed samples. Then the magnitudes
of each of the frequencies that compose the signal are calculated. Finally,
the frequency spectrum magnitudes are printed. If you use the Arduino IDE
serial plotter, you will see a single spike corresponding to the 1000 Hz
frequency.
*/
#include "arduinoFFT.h"
/*
These values can be changed in order to evaluate the functions
*/
const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2
const double signalFrequency = 1000;
const double samplingFrequency = 5000;
const uint8_t amplitude = 100;
/*
These are the input and output vectors
Input vectors receive computed results from FFT
*/
double vReal[samples];
double vImag[samples];
ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency);
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03
void setup()
{
Serial.begin(115200);
while(!Serial);
Serial.println("Ready");
}
void loop()
{
/* Build raw data */
double ratio = twoPi * signalFrequency / samplingFrequency; // Fraction of a complete cycle stored at each sample (in radians)
for (uint16_t i = 0; i < samples; i++)
{
vReal[i] = int8_t(amplitude * sin(i * ratio) / 2.0);/* Build data with positive and negative values*/
//vReal[i] = uint8_t((amplitude * (sin(i * ratio) + 1.0)) / 2.0);/* Build data displaced on the Y axis to include only positive values*/
vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
}
FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */
FFT.compute(FFTDirection::Forward); /* Compute FFT */
FFT.complexToMagnitude(); /* Compute magnitudes */
PrintVector(vReal, samples>>1, SCL_PLOT);
double x = FFT.majorPeak();
while(1); /* Run Once */
// delay(2000); /* Repeat after delay */
}
void PrintVector(double *vData, uint16_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;
}
if(scaleType!=SCL_PLOT)
{
Serial.print(abscissa, 6);
if(scaleType==SCL_FREQUENCY)
Serial.print("Hz");
Serial.print(" ");
}
Serial.println(vData[i], 4);
}
Serial.println();
}

Wyświetl plik

@ -0,0 +1,125 @@
/*
Example of use of the FFT library
Copyright (C) 2014 Enrique Condes
Copyright (C) 2020 Bim Overbohm (template, speed improvements)
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 <http://www.gnu.org/licenses/>.
*/
/*
In this example, the Arduino simulates the sampling of a sinusoidal 1000 Hz
signal with an amplitude of 100, sampled at 5000 Hz. Samples are stored
inside the vReal array. The samples are windowed according to Hamming
function. The FFT is computed using the windowed samples. Then the magnitudes
of each of the frequencies that compose the signal are calculated. Finally,
the frequency with the highest peak is obtained, being that the main frequency
present in the signal. This frequency is printed, along with the magnitude of
the peak.
*/
#include "arduinoFFT.h"
/*
These values can be changed in order to evaluate the functions
*/
const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2
const double signalFrequency = 1000;
const double samplingFrequency = 5000;
const uint8_t amplitude = 100;
/*
These are the input and output vectors
Input vectors receive computed results from FFT
*/
double vReal[samples];
double vImag[samples];
/* Create FFT object */
ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency);
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03
void setup()
{
Serial.begin(115200);
while(!Serial);
Serial.println("Ready");
}
void loop()
{
/* Build raw data */
double ratio = twoPi * signalFrequency / samplingFrequency; // Fraction of a complete cycle stored at each sample (in radians)
for (uint16_t i = 0; i < samples; i++)
{
vReal[i] = int8_t(amplitude * sin(i * ratio) / 2.0);/* Build data with positive and negative values*/
//vReal[i] = uint8_t((amplitude * (sin(i * ratio) + 1.0)) / 2.0);/* Build data displaced on the Y axis to include only positive values*/
vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
}
/* Print the results of the simulated sampling according to time */
Serial.println("Data:");
PrintVector(vReal, samples, SCL_TIME);
FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */
Serial.println("Weighed data:");
PrintVector(vReal, samples, SCL_TIME);
FFT.compute(FFTDirection::Forward); /* Compute FFT */
Serial.println("Computed Real values:");
PrintVector(vReal, samples, SCL_INDEX);
Serial.println("Computed Imaginary values:");
PrintVector(vImag, samples, SCL_INDEX);
FFT.complexToMagnitude(); /* Compute magnitudes */
Serial.println("Computed magnitudes:");
PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);
double x;
double v;
FFT.majorPeak(&x, &v);
Serial.print(x, 6);
Serial.print(", ");
Serial.println(v, 6);
while(1); /* Run Once */
// delay(2000); /* Repeat after delay */
}
void PrintVector(double *vData, uint16_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);
if(scaleType==SCL_FREQUENCY)
Serial.print("Hz");
Serial.print(" ");
Serial.println(vData[i], 4);
}
Serial.println();
}

Wyświetl plik

@ -0,0 +1,123 @@
/*
Example of use of the FFT library to compute FFT for a signal sampled through the ADC
with speedup through different arduinoFFT options. Based on examples/FFT_03/FFT_03.ino
Copyright (C) 2020 Bim Overbohm (template, speed improvements)
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 <http://www.gnu.org/licenses/>.
*/
// There are two speedup options for some of the FFT code:
// Define this to use reciprocal multiplication for division and some more speedups that might decrease precision
//#define FFT_SPEED_OVER_PRECISION
// Define this to use a low-precision square root approximation instead of the regular sqrt() call
// This might only work for specific use cases, but is significantly faster. Only works for ArduinoFFT<float>.
//#define FFT_SQRT_APPROXIMATION
#include "arduinoFFT.h"
/*
These values can be changed in order to evaluate the functions
*/
#define CHANNEL A0
const uint16_t samples = 64; //This value MUST ALWAYS be a power of 2
const float samplingFrequency = 100; //Hz, must be less than 10000 due to ADC
unsigned int sampling_period_us;
unsigned long microseconds;
/*
These are the input and output vectors
Input vectors receive computed results from FFT
*/
float vReal[samples];
float vImag[samples];
/* Create FFT object with weighing factor storage */
ArduinoFFT<float> FFT = ArduinoFFT<float>(vReal, vImag, samples, samplingFrequency, true);
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03
void setup()
{
sampling_period_us = round(1000000*(1.0/samplingFrequency));
Serial.begin(115200);
Serial.println("Ready");
}
void loop()
{
/*SAMPLING*/
microseconds = micros();
for(int i=0; i<samples; i++)
{
vReal[i] = analogRead(CHANNEL);
vImag[i] = 0;
while(micros() - microseconds < sampling_period_us){
//empty loop
}
microseconds += sampling_period_us;
}
/* Print the results of the sampling according to time */
Serial.println("Data:");
PrintVector(vReal, samples, SCL_TIME);
FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward); /* Weigh data */
Serial.println("Weighed data:");
PrintVector(vReal, samples, SCL_TIME);
FFT.compute(FFTDirection::Forward); /* Compute FFT */
Serial.println("Computed Real values:");
PrintVector(vReal, samples, SCL_INDEX);
Serial.println("Computed Imaginary values:");
PrintVector(vImag, samples, SCL_INDEX);
FFT.complexToMagnitude(); /* Compute magnitudes */
Serial.println("Computed magnitudes:");
PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);
float x = FFT.majorPeak();
Serial.println(x, 6); //Print out what frequency is the most dominant.
while(1); /* Run Once */
// delay(2000); /* Repeat after delay */
}
void PrintVector(float *vData, uint16_t bufferSize, uint8_t scaleType)
{
for (uint16_t i = 0; i < bufferSize; i++)
{
float 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);
if(scaleType==SCL_FREQUENCY)
Serial.print("Hz");
Serial.print(" ");
Serial.println(vData[i], 4);
}
Serial.println();
}

Wyświetl plik

@ -1,66 +1,38 @@
arduinoFFT
==========
Fast Fourier Transform for Arduino
# Fast Fourier Transform for Arduino
This is a fork from https://code.google.com/p/makefurt/ which has been abandoned since 2011.
<del>This is a C++ library for Arduino for computing FFT.</del> Now it works both on Arduino and C projects.
This is version 2.0 of the library, which has a different [API](#api).
Tested on Arduino 1.6.11
Tested on Arduino 1.8.19 and 2.3.2.
### Installation on Arduino
## Installation on Arduino
To install this library, just place this entire folder as a subfolder in your Arduino installation
Use the Arduino Library Manager to install and keep it updated. Just look for arduinoFFT. Only for Arduino 1.5+
When installed, this library should look like:
## Manual installation on Arduino
Arduino\libraries\arduinoFTT (this library's folder)
Arduino\libraries\arduinoFTT\arduinoFTT.cpp (the library implementation file, uses 32 bits floats vectors)
Arduino\libraries\arduinoFTT\arduinoFTT.h (the library header file, uses 32 bits floats vectors)
Arduino\libraries\arduinoFTT\keywords.txt (the syntax coloring file)
Arduino\libraries\arduinoFTT\examples (the examples in the "open" menu)
Arduino\libraries\arduinoFTT\readme.md (this file)
To install this library, just place this entire folder as a subfolder in your Arduino installation. When installed, this library should look like:
### Building on Arduino
`Arduino\libraries\arduinoFTT` (this library's folder)
`Arduino\libraries\arduinoFTT\src\arduinoFTT.h` (the library header file. include this in your project)
`Arduino\libraries\arduinoFTT\keywords.txt` (the syntax coloring file)
`Arduino\libraries\arduinoFTT\Examples` (the examples in the "open" menu)
`Arduino\libraries\arduinoFTT\LICENSE` (GPL license file)
`Arduino\libraries\arduinoFTT\README.md` (this file)
## Building on Arduino
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 arduinoFTT. This will add a corresponding line to the top of your sketch:
`#include <arduinoFTT.h>`
### TODO
* Ratio table for windowing function.
* Document windowing functions advantages and disadvantages.
* Optimize usage and arguments.
* Add new windowing functions.
* Spectrum table?
## API
### API
* **arduinoFFT**(void);
Constructor
* **~arduinoFFT**(void);
Destructor
* **ComplexToMagnitude**(double *vReal, double *vImag, uint16_t samples);
* **Compute**(double *vReal, double *vImag, uint16_t samples, uint8_t dir);
Calculates the power value according to **Exponent** and calcuates the Fast Fourier Transform.
* **Compute**(double *vReal, double *vImag, uint16_t samples, uint8_t power, uint8_t dir);
Calcuates the Fast Fourier Transform.
* **MajorPeak**(double *vD, uint16_t samples, double samplingFrequency);
* **Revision**(void);
Returns the library revision.
* **Windowing**(double *vData, uint16_t samples, uint8_t windowType, uint8_t dir);
Performs a windowing function on the values array. The possible windowing options are:
* FFT_WIN_TYP_RECTANGLE
* FFT_WIN_TYP_HAMMING
* FFT_WIN_TYP_HANN
* FFT_WIN_TYP_TRIANGLE
* FFT_WIN_TYP_BLACKMAN
* FFT_WIN_TYP_FLT_TOP
* FFT_WIN_TYP_WELCH
* **Exponent**(uint16_t value);
Calculates and returns the base 2 logarithm of the given value.
Documentation was moved to the project's [wiki](https://github.com/kosme/arduinoFFT/wiki).

Wyświetl plik

@ -3,18 +3,40 @@
#######################################
#######################################
# Datatypes (KEYWORD1)
# Datatypes (KEYWORD1)
#######################################
arduinoFFT KEYWORD1
ArduinoFFT KEYWORD1
FFTDirection KEYWORD1
FFTWindow KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
ComplexToMagnitude KEYWORD2
Compute KEYWORD2
Windowing KEYWORD2
Exponent KEYWORD2
Revision KEYWORD2
MajorPeak KEYWORD2
complexToMagnitude KEYWORD2
compute KEYWORD2
dcRemoval KEYWORD2
majorPeak KEYWORD2
majorPeakParabola KEYWORD2
revision KEYWORD2
setArrays KEYWORD2
windowing KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
Forward LITERAL1
Reverse LITERAL1
Blackman LITERAL1
Blackman_Harris LITERAL1
Blackman_Nuttall LITERAL1
Flat_top LITERAL1
Hamming LITERAL1
Hann LITERAL1
Nuttall LITERAL1
Rectangle LITERAL1
Triangle LITERAL1
Welch LITERAL1

32
library.json 100644
Wyświetl plik

@ -0,0 +1,32 @@
{
"name": "arduinoFFT",
"keywords": "FFT, Fourier, FDT, frequency",
"description": "A library for implementing floating point Fast Fourier Transform calculations.",
"repository":
{
"type": "git",
"url": "https://github.com/kosme/arduinoFFT.git"
},
"authors":
[
{
"name": "Enrique Condes",
"email": "enrique@shapeoko.com",
"maintainer": true
},
{
"name": "Didier Longueville",
"url": "http://www.arduinoos.com/",
"email": "contact@arduinoos.com"
},
{
"name": "Bim Overbohm",
"url": "https://github.com/HorstBaerbel",
"email": "bim.overbohm@googlemail.com"
}
],
"version": "2.0.2",
"frameworks": ["arduino","mbed","espidf"],
"platforms": "*",
"headers": "arduinoFFT.h"
}

Wyświetl plik

@ -1,9 +1,9 @@
name=arduinoFFT
version=1.2.3
author=kosme <enrique@shapeoko.com>
version=2.0.2
author=Enrique Condes <enrique@shapeoko.com>
maintainer=Enrique Condes <enrique@shapeoko.com>
sentence=A library for implementing Fast Fourier Transform on Arduino.
paragraph=With this library you can calculate the frequency of a sampled signal.
sentence=A library for implementing floating point Fast Fourier Transform calculations on the Arduino framework.
paragraph=With this library you can calculate the dominant frequency of a sampled signal.
category=Data Processing
url=https://github.com/kosme/arduinoFFT
architectures=*

1
src/.gitignore vendored 100644
Wyświetl plik

@ -0,0 +1 @@
/arduinoFFT.h.gch

Wyświetl plik

@ -1,184 +1,525 @@
/*
FFT library
Copyright (C) 2010 Didier Longueville
Copyright (C) 2014 Enrique Condes
Copyright (C) 2020 Bim Overbohm (template, speed improvements)
FFT libray
Copyright (C) 2010 Didier Longueville
Copyright (C) 2014 Enrique Condes
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 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.
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 <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arduinoFFT.h"
arduinoFFT::arduinoFFT(void)
{
/* Constructor */
template <typename T> ArduinoFFT<T>::ArduinoFFT() {}
template <typename T>
ArduinoFFT<T>::ArduinoFFT(T *vReal, T *vImag, uint_fast16_t samples,
T samplingFrequency, bool windowingFactors)
: _samples(samples), _samplingFrequency(samplingFrequency), _vImag(vImag),
_vReal(vReal) {
if (windowingFactors) {
_precompiledWindowingFactors = new T[samples / 2];
}
_power = exponent(samples);
#ifdef FFT_SPEED_OVER_PRECISION
_oneOverSamples = 1.0 / samples;
#endif
}
arduinoFFT::~arduinoFFT(void)
{
/* Destructor */
template <typename T> ArduinoFFT<T>::~ArduinoFFT(void) {
// Destructor
if (_precompiledWindowingFactors) {
delete[] _precompiledWindowingFactors;
}
}
uint8_t arduinoFFT::Revision(void)
{
return(FFT_LIB_REV);
template <typename T> void ArduinoFFT<T>::complexToMagnitude(void) const {
complexToMagnitude(this->_vReal, this->_vImag, this->_samples);
}
void arduinoFFT::Compute(double *vReal, double *vImag, uint16_t samples, uint8_t dir)
{
Compute(vReal, vImag, samples, Exponent(samples), dir);
template <typename T>
void ArduinoFFT<T>::complexToMagnitude(T *vReal, T *vImag,
uint_fast16_t samples) const {
// vM is half the size of vReal and vImag
for (uint_fast16_t i = 0; i < samples; i++) {
vReal[i] = sqrt_internal(sq(vReal[i]) + sq(vImag[i]));
}
}
void arduinoFFT::Compute(double *vReal, double *vImag, uint16_t samples, uint8_t power, 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;
uint16_t l2 = 1;
for (uint8_t l = 0; (l < power); l++) {
uint16_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;
}
}
template <typename T> void ArduinoFFT<T>::compute(FFTDirection dir) const {
compute(this->_vReal, this->_vImag, this->_samples, exponent(this->_samples),
dir);
}
void arduinoFFT::ComplexToMagnitude(double *vReal, double *vImag, uint16_t samples)
{
/* vM is half the size of vReal and vImag */
for (uint16_t i = 0; i < samples; i++) {
vReal[i] = sqrt(sq(vReal[i]) + sq(vImag[i]));
}
template <typename T>
void ArduinoFFT<T>::compute(T *vReal, T *vImag, uint_fast16_t samples,
FFTDirection dir) const {
compute(vReal, vImag, samples, exponent(samples), dir);
}
void arduinoFFT::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;
}
}
// Computes in-place complex-to-complex FFT
template <typename T>
void ArduinoFFT<T>::compute(T *vReal, T *vImag, uint_fast16_t samples,
uint_fast8_t power, FFTDirection dir) const {
#ifdef FFT_SPEED_OVER_PRECISION
T oneOverSamples = this->_oneOverSamples;
if (!this->_oneOverSamples)
oneOverSamples = 1.0 / samples;
#endif
// Reverse bits
uint_fast16_t j = 0;
for (uint_fast16_t i = 0; i < (samples - 1); i++) {
if (i < j) {
swap(&vReal[i], &vReal[j]);
if (dir == FFTDirection::Reverse)
swap(&vImag[i], &vImag[j]);
}
uint_fast16_t k = (samples >> 1);
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
// Compute the FFT
T c1 = -1.0;
T c2 = 0.0;
uint_fast16_t l2 = 1;
for (uint_fast8_t l = 0; (l < power); l++) {
uint_fast16_t l1 = l2;
l2 <<= 1;
T u1 = 1.0;
T u2 = 0.0;
for (j = 0; j < l1; j++) {
for (uint_fast16_t i = j; i < samples; i += l2) {
uint_fast16_t i1 = i + l1;
T t1 = u1 * vReal[i1] - u2 * vImag[i1];
T t2 = u1 * vImag[i1] + u2 * vReal[i1];
vReal[i1] = vReal[i] - t1;
vImag[i1] = vImag[i] - t2;
vReal[i] += t1;
vImag[i] += t2;
}
T z = ((u1 * c1) - (u2 * c2));
u2 = ((u1 * c2) + (u2 * c1));
u1 = z;
}
#if defined(__AVR__) && defined(USE_AVR_PROGMEM)
c2 = pgm_read_float_near(&(_c2[l]));
c1 = pgm_read_float_near(&(_c1[l]));
#else
T cTemp = 0.5 * c1;
c2 = sqrt_internal(0.5 - cTemp);
c1 = sqrt_internal(0.5 + cTemp);
#endif
if (dir == FFTDirection::Forward) {
c2 = -c2;
}
}
// Scaling for reverse transform
if (dir == FFTDirection::Reverse) {
for (uint_fast16_t i = 0; i < samples; i++) {
#ifdef FFT_SPEED_OVER_PRECISION
vReal[i] *= oneOverSamples;
vImag[i] *= oneOverSamples;
#else
vReal[i] /= samples;
vImag[i] /= samples;
#endif
}
}
// The computation result at position 0 should be as close to 0 as possible.
// The DC offset on the signal produces a spike on position 0 that should be
// eliminated to avoid issues.
vReal[0] = 0;
}
double arduinoFFT::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);
template <typename T> void ArduinoFFT<T>::dcRemoval(void) const {
dcRemoval(this->_vReal, this->_samples);
}
/* Private functions */
void arduinoFFT::Swap(double *x, double *y)
{
double temp = *x;
*x = *y;
*y = temp;
template <typename T>
void ArduinoFFT<T>::dcRemoval(T *vData, uint_fast16_t samples) const {
// calculate the mean of vData
T mean = 0;
for (uint_fast16_t i = 0; i < samples; i++) {
mean += vData[i];
}
mean /= samples;
// Subtract the mean from vData
for (uint_fast16_t i = 0; i < samples; i++) {
vData[i] -= mean;
}
}
uint8_t arduinoFFT::Exponent(uint16_t value)
{
/* Calculates the base 2 logarithm of a value */
uint8_t result = 0;
while (((value >> result) & 1) != 1) result++;
return(result);
template <typename T> T ArduinoFFT<T>::majorPeak(void) const {
return majorPeak(this->_vReal, this->_samples, this->_samplingFrequency);
}
template <typename T> void ArduinoFFT<T>::majorPeak(T *f, T *v) const {
majorPeak(this->_vReal, this->_samples, this->_samplingFrequency, f, v);
}
template <typename T>
T ArduinoFFT<T>::majorPeak(T *vData, uint_fast16_t samples,
T samplingFrequency) const {
T frequency;
majorPeak(vData, samples, samplingFrequency, &frequency, nullptr);
return frequency;
}
template <typename T>
void ArduinoFFT<T>::majorPeak(T *vData, uint_fast16_t samples,
T samplingFrequency, T *frequency,
T *magnitude) const {
T maxY = 0;
uint_fast16_t IndexOfMaxY = 0;
findMaxY(vData, (samples >> 1) + 1, &maxY, &IndexOfMaxY);
T delta = 0.5 * ((vData[IndexOfMaxY - 1] - vData[IndexOfMaxY + 1]) /
(vData[IndexOfMaxY - 1] - (2.0 * vData[IndexOfMaxY]) +
vData[IndexOfMaxY + 1]));
T interpolatedX = ((IndexOfMaxY + delta) * samplingFrequency) / (samples - 1);
if (IndexOfMaxY == (samples >> 1)) // To improve calculation on edge values
interpolatedX = ((IndexOfMaxY + delta) * samplingFrequency) / (samples);
// returned value: interpolated frequency peak apex
*frequency = interpolatedX;
if (magnitude != nullptr) {
#if defined(ESP8266) || defined(ESP32)
*magnitude = fabs(vData[IndexOfMaxY - 1] - (2.0 * vData[IndexOfMaxY]) +
vData[IndexOfMaxY + 1]);
#else
*magnitude = abs(vData[IndexOfMaxY - 1] - (2.0 * vData[IndexOfMaxY]) +
vData[IndexOfMaxY + 1]);
#endif
}
}
template <typename T> T ArduinoFFT<T>::majorPeakParabola(void) const {
T freq = 0;
majorPeakParabola(this->_vReal, this->_samples, this->_samplingFrequency,
&freq, nullptr);
return freq;
}
template <typename T>
void ArduinoFFT<T>::majorPeakParabola(T *frequency, T *magnitude) const {
majorPeakParabola(this->_vReal, this->_samples, this->_samplingFrequency,
frequency, magnitude);
}
template <typename T>
T ArduinoFFT<T>::majorPeakParabola(T *vData, uint_fast16_t samples,
T samplingFrequency) const {
T freq = 0;
majorPeakParabola(vData, samples, samplingFrequency, &freq, nullptr);
return freq;
}
template <typename T>
void ArduinoFFT<T>::majorPeakParabola(T *vData, uint_fast16_t samples,
T samplingFrequency, T *frequency,
T *magnitude) const {
T maxY = 0;
uint_fast16_t IndexOfMaxY = 0;
findMaxY(vData, (samples >> 1) + 1, &maxY, &IndexOfMaxY);
*frequency = 0;
if (IndexOfMaxY > 0) {
// Assume the three points to be on a parabola
T a, b, c;
parabola(IndexOfMaxY - 1, vData[IndexOfMaxY - 1], IndexOfMaxY,
vData[IndexOfMaxY], IndexOfMaxY + 1, vData[IndexOfMaxY + 1], &a,
&b, &c);
// Peak is at the middle of the parabola
T x = -b / (2 * a);
// And magnitude is at the extrema of the parabola if you want It...
if (magnitude != nullptr) {
*magnitude = (a * x * x) + (b * x) + c;
}
// Convert to frequency
*frequency = (x * samplingFrequency) / samples;
}
}
template <typename T> uint8_t ArduinoFFT<T>::revision(void) {
return (FFT_LIB_REV);
}
// Replace the data array pointers
template <typename T>
void ArduinoFFT<T>::setArrays(T *vReal, T *vImag, uint_fast16_t samples) {
_vReal = vReal;
_vImag = vImag;
if (samples) {
_samples = samples;
#ifdef FFT_SPEED_OVER_PRECISION
_oneOverSamples = 1.0 / samples;
#endif
if (_precompiledWindowingFactors) {
delete[] _precompiledWindowingFactors;
}
_precompiledWindowingFactors = new T[samples / 2];
}
}
template <typename T>
void ArduinoFFT<T>::windowing(FFTWindow windowType, FFTDirection dir,
bool withCompensation) {
// The windowing function is the same, precompiled values can be used, and
// precompiled values exist
if (this->_precompiledWindowingFactors && this->_isPrecompiled &&
this->_windowFunction == windowType &&
this->_precompiledWithCompensation == withCompensation) {
windowing(this->_vReal, this->_samples, FFTWindow::Precompiled, dir,
this->_precompiledWindowingFactors, withCompensation);
// Precompiled values must be generated. Either the function changed or the
// precompiled values don't exist
} else if (this->_precompiledWindowingFactors) {
windowing(this->_vReal, this->_samples, windowType, dir,
this->_precompiledWindowingFactors, withCompensation);
this->_isPrecompiled = true;
this->_precompiledWithCompensation = withCompensation;
this->_windowFunction = windowType;
// Don't care about precompiled windowing values
} else {
windowing(this->_vReal, this->_samples, windowType, dir, nullptr,
withCompensation);
}
}
template <typename T>
void ArduinoFFT<T>::windowing(T *vData, uint_fast16_t samples,
FFTWindow windowType, FFTDirection dir,
T *windowingFactors, bool withCompensation) {
// Weighing factors are computed once before multiple use of FFT
// The weighing function is symmetric; half the weighs are recorded
if (windowingFactors != nullptr && windowType == FFTWindow::Precompiled) {
for (uint_fast16_t i = 0; i < (samples >> 1); i++) {
if (dir == FFTDirection::Forward) {
vData[i] *= windowingFactors[i];
vData[samples - (i + 1)] *= windowingFactors[i];
} else {
#ifdef FFT_SPEED_OVER_PRECISION
T inverse = 1.0 / windowingFactors[i];
vData[i] *= inverse;
vData[samples - (i + 1)] *= inverse;
#else
vData[i] /= windowingFactors[i];
vData[samples - (i + 1)] /= windowingFactors[i];
#endif
}
}
} else {
T samplesMinusOne = (T(samples) - 1.0);
T compensationFactor;
if (withCompensation) {
compensationFactor =
_WindowCompensationFactors[static_cast<uint_fast8_t>(windowType)];
}
for (uint_fast16_t i = 0; i < (samples >> 1); i++) {
T indexMinusOne = T(i);
T ratio = (indexMinusOne / samplesMinusOne);
T weighingFactor = 1.0;
// Compute and record weighting factor
switch (windowType) {
case FFTWindow::Hamming: // hamming
weighingFactor = 0.54 - (0.46 * cos(twoPi * ratio));
break;
case FFTWindow::Hann: // hann
weighingFactor = 0.54 * (1.0 - cos(twoPi * ratio));
break;
case FFTWindow::Triangle: // triangle (Bartlett)
#if defined(ESP8266) || defined(ESP32)
weighingFactor =
1.0 - ((2.0 * fabs(indexMinusOne - (samplesMinusOne / 2.0))) /
samplesMinusOne);
#else
weighingFactor =
1.0 - ((2.0 * abs(indexMinusOne - (samplesMinusOne / 2.0))) /
samplesMinusOne);
#endif
break;
case FFTWindow::Nuttall: // nuttall
weighingFactor = 0.355768 - (0.487396 * (cos(twoPi * ratio))) +
(0.144232 * (cos(fourPi * ratio))) -
(0.012604 * (cos(sixPi * ratio)));
break;
case FFTWindow::Blackman: // blackman
weighingFactor = 0.42323 - (0.49755 * (cos(twoPi * ratio))) +
(0.07922 * (cos(fourPi * ratio)));
break;
case FFTWindow::Blackman_Nuttall: // blackman nuttall
weighingFactor = 0.3635819 - (0.4891775 * (cos(twoPi * ratio))) +
(0.1365995 * (cos(fourPi * ratio))) -
(0.0106411 * (cos(sixPi * ratio)));
break;
case FFTWindow::Blackman_Harris: // blackman harris
weighingFactor = 0.35875 - (0.48829 * (cos(twoPi * ratio))) +
(0.14128 * (cos(fourPi * ratio))) -
(0.01168 * (cos(sixPi * ratio)));
break;
case FFTWindow::Flat_top: // flat top
weighingFactor = 0.2810639 - (0.5208972 * cos(twoPi * ratio)) +
(0.1980399 * cos(fourPi * ratio));
break;
case FFTWindow::Welch: // welch
weighingFactor = 1.0 - sq((indexMinusOne - samplesMinusOne / 2.0) /
(samplesMinusOne / 2.0));
break;
default:
// This is Rectangle windowing which doesn't do anything
// and Precompiled which shouldn't be selected
break;
}
if (withCompensation) {
weighingFactor *= compensationFactor;
}
if (windowingFactors) {
windowingFactors[i] = weighingFactor;
}
if (dir == FFTDirection::Forward) {
vData[i] *= weighingFactor;
vData[samples - (i + 1)] *= weighingFactor;
} else {
#ifdef FFT_SPEED_OVER_PRECISION
T inverse = 1.0 / weighingFactor;
vData[i] *= inverse;
vData[samples - (i + 1)] *= inverse;
#else
vData[i] /= weighingFactor;
vData[samples - (i + 1)] /= weighingFactor;
#endif
}
}
}
}
// Private functions
template <typename T>
uint_fast8_t ArduinoFFT<T>::exponent(uint_fast16_t value) const {
// Calculates the base 2 logarithm of a value
uint_fast8_t result = 0;
while (value >>= 1)
result++;
return result;
}
template <typename T>
void ArduinoFFT<T>::findMaxY(T *vData, uint_fast16_t length, T *maxY,
uint_fast16_t *index) const {
*maxY = 0;
*index = 0;
// If sampling_frequency = 2 * max_frequency in signal,
// value would be stored at position samples/2
for (uint_fast16_t i = 1; i < length; i++) {
if ((vData[i - 1] < vData[i]) && (vData[i] > vData[i + 1])) {
if (vData[i] > vData[*index]) {
*index = i;
}
}
}
*maxY = vData[*index];
}
template <typename T>
void ArduinoFFT<T>::parabola(T x1, T y1, T x2, T y2, T x3, T y3, T *a, T *b,
T *c) const {
// const T reversed_denom = 1 / ((x1 - x2) * (x1 - x3) * (x2 - x3));
// This is a special case in which the three X coordinates are three positive,
// consecutive integers. Therefore the reverse denominator will always be -0.5
const T reversed_denom = -0.5;
*a = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) * reversed_denom;
*b = (x3 * x3 * (y1 - y2) + x2 * x2 * (y3 - y1) + x1 * x1 * (y2 - y3)) *
reversed_denom;
*c = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 +
x1 * x2 * (x1 - x2) * y3) *
reversed_denom;
}
template <typename T> void ArduinoFFT<T>::swap(T *a, T *b) const {
T temp = *a;
*a = *b;
*b = temp;
}
#ifdef FFT_SQRT_APPROXIMATION
// Fast inverse square root aka "Quake 3 fast inverse square root", multiplied
// by x. Uses one iteration of Halley's method for precision. See:
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots
// And: https://github.com/HorstBaerbel/approx
template <typename T> float ArduinoFFT<T>::sqrt_internal(float x) const {
union // get bits for floating point value
{
float x;
int32_t i;
} u;
u.x = x;
u.i = 0x5f375a86 - (u.i >> 1); // gives initial guess y0.
float xu = x * u.x;
float xu2 = xu * u.x;
// Halley's method, repeating increases accuracy
u.x = (0.125 * 3.0) * xu * (5.0 - xu2 * ((10.0 / 3.0) - xu2));
return u.x;
}
template <typename T> double ArduinoFFT<T>::sqrt_internal(double x) const {
// According to HosrtBaerbel, on the ESP32 the approximation is not faster, so
// we use the standard function
#ifdef ESP32
return sqrt(x);
#else
union // get bits for floating point value
{
double x;
int64_t i;
} u;
u.x = x;
u.i = 0x5fe6ec85e7de30da - (u.i >> 1); // gives initial guess y0.
double xu = x * u.x;
double xu2 = xu * u.x;
// Halley's method, repeating increases accuracy
u.x = (0.125 * 3.0) * xu * (5.0 - xu2 * ((10.0 / 3.0) - xu2));
return u.x;
#endif
}
#endif
template <typename T>
const T ArduinoFFT<T>::_WindowCompensationFactors[11] = {
1.0000000000 * 2.0, // rectangle (Box car)
1.8549343278 * 2.0, // hamming
1.8554726898 * 2.0, // hann
2.0039186079 * 2.0, // triangle (Bartlett)
2.8163172034 * 2.0, // nuttall
2.3673474360 * 2.0, // blackman
2.7557840395 * 2.0, // blackman nuttall
2.7929062517 * 2.0, // blackman harris
3.5659039231 * 2.0, // flat top
1.5029392863 * 2.0, // welch
// This is added as a precaution, since this index should never be
// accessed under normal conditions
1.0 // Custom, precompiled value.
};
template class ArduinoFFT<double>;
template class ArduinoFFT<float>;

Wyświetl plik

@ -1,76 +1,142 @@
/*
FFT libray
Copyright (C) 2010 Didier Longueville
Copyright (C) 2014 Enrique Condes
FFT library
Copyright (C) 2010 Didier Longueville
Copyright (C) 2014 Enrique Condes
Copyright (C) 2020 Bim Overbohm (template, speed improvements)
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 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.
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 <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef arduinoFFT_h /* Prevent loading library twice */
#define arduinoFFT_h
#ifndef ArduinoFFT_h /* Prevent loading library twice */
#define ArduinoFFT_h
#ifdef ARDUINO
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h" /* This is where the standard Arduino code lies */
#endif
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <math.h>
#include "defs.h"
#include "types.h"
#include "WProgram.h" /* This is where the standard Arduino code lies */
#endif
#else
#include <stdio.h>
#include <stdlib.h>
#ifdef __AVR__
#include <avr/io.h>
#include <avr/pgmspace.h>
#endif
#include "defs.h"
#include "types.h"
#include <math.h>
#include <stdint.h>
#endif
#include "enumsFFT.h"
// This definition uses a low-precision square root approximation instead of the
// regular sqrt() call
// This might only work for specific use cases, but is significantly faster.
#ifndef FFT_SQRT_APPROXIMATION
#ifndef sqrt_internal
#define sqrt_internal sqrt
#endif
#endif
#define FFT_LIB_REV 0x02c
/* 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 */
/*Mathematial constants*/
#define twoPi 6.28318531
#define fourPi 12.56637061
#define FFT_LIB_REV 0x20
class arduinoFFT {
template <typename T> class ArduinoFFT {
public:
/* Constructor */
arduinoFFT(void);
/* Destructor */
~arduinoFFT(void);
/* Functions */
void ComplexToMagnitude(double *vReal, double *vImag, uint16_t samples);
void Compute(double *vReal, double *vImag, uint16_t samples, uint8_t dir);
void Compute(double *vReal, double *vImag, uint16_t samples, uint8_t power, 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);
uint8_t Exponent(uint16_t value);
ArduinoFFT();
ArduinoFFT(T *vReal, T *vImag, uint_fast16_t samples, T samplingFrequency,
bool windowingFactors = false);
~ArduinoFFT();
void complexToMagnitude(void) const;
void complexToMagnitude(T *vReal, T *vImag, uint_fast16_t samples) const;
void compute(FFTDirection dir) const;
void compute(T *vReal, T *vImag, uint_fast16_t samples,
FFTDirection dir) const;
void compute(T *vReal, T *vImag, uint_fast16_t samples, uint_fast8_t power,
FFTDirection dir) const;
void dcRemoval(void) const;
void dcRemoval(T *vData, uint_fast16_t samples) const;
T majorPeak(void) const;
void majorPeak(T *f, T *v) const;
T majorPeak(T *vData, uint_fast16_t samples, T samplingFrequency) const;
void majorPeak(T *vData, uint_fast16_t samples, T samplingFrequency,
T *frequency, T *magnitude) const;
T majorPeakParabola(void) const;
void majorPeakParabola(T *frequency, T *magnitude) const;
T majorPeakParabola(T *vData, uint_fast16_t samples,
T samplingFrequency) const;
void majorPeakParabola(T *vData, uint_fast16_t samples, T samplingFrequency,
T *frequency, T *magnitude) const;
uint8_t revision(void);
void setArrays(T *vReal, T *vImag, uint_fast16_t samples = 0);
void windowing(FFTWindow windowType, FFTDirection dir,
bool withCompensation = false);
void windowing(T *vData, uint_fast16_t samples, FFTWindow windowType,
FFTDirection dir, T *windowingFactors = nullptr,
bool withCompensation = false);
private:
/* Functions */
void Swap(double *x, double *y);
/* Variables */
static const T _WindowCompensationFactors[11];
#ifdef FFT_SPEED_OVER_PRECISION
T _oneOverSamples = 0.0;
#endif
bool _isPrecompiled = false;
bool _precompiledWithCompensation = false;
uint_fast8_t _power = 0;
T *_precompiledWindowingFactors = nullptr;
uint_fast16_t _samples;
T _samplingFrequency;
T *_vImag;
T *_vReal;
FFTWindow _windowFunction;
/* Functions */
uint_fast8_t exponent(uint_fast16_t value) const;
void findMaxY(T *vData, uint_fast16_t length, T *maxY,
uint_fast16_t *index) const;
void parabola(T x1, T y1, T x2, T y2, T x3, T y3, T *a, T *b, T *c) const;
void swap(T *a, T *b) const;
#ifdef FFT_SQRT_APPROXIMATION
float sqrt_internal(float x) const;
double sqrt_internal(double x) const;
#endif
};
#if defined(__AVR__) && defined(USE_AVR_PROGMEM)
static const float _c1[] PROGMEM = {
0.0000000000, 0.7071067812, 0.9238795325, 0.9807852804, 0.9951847267,
0.9987954562, 0.9996988187, 0.9999247018, 0.9999811753, 0.9999952938,
0.9999988235, 0.9999997059, 0.9999999265, 0.9999999816, 0.9999999954,
0.9999999989, 0.9999999997};
static const float _c2[] PROGMEM = {
1.0000000000, 0.7071067812, 0.3826834324, 0.1950903220, 0.0980171403,
0.0490676743, 0.0245412285, 0.0122715383, 0.0061358846, 0.0030679568,
0.0015339802, 0.0007669903, 0.0003834952, 0.0001917476, 0.0000958738,
0.0000479369, 0.0000239684};
#endif
#endif

43
src/enumsFFT.h 100644
Wyświetl plik

@ -0,0 +1,43 @@
#ifndef enumsFFT_h
#define enumsFFT_h
/* Custom constants */
/* These defines keep compatibility with pre 2.0 code */
#define FFT_FORWARD FFTDirection::Forward
#define FFT_REVERSE FFTDirection::Reverse
/* Windowing type */
#define FFT_WIN_TYP_RECTANGLE FFTWindow::Rectangle /* rectangle (Box car) */
#define FFT_WIN_TYP_HAMMING FFTWindow::Hamming /* hamming */
#define FFT_WIN_TYP_HANN FFTWindow::Hann /* hann */
#define FFT_WIN_TYP_TRIANGLE FFTWindow::Triangle /* triangle (Bartlett) */
#define FFT_WIN_TYP_NUTTALL FFTWindow::Nuttall /* nuttall */
#define FFT_WIN_TYP_BLACKMAN FFTWindow::Blackman /* blackman */
#define FFT_WIN_TYP_BLACKMAN_NUTTALL \
FFTWindow::Blackman_Nuttall /* blackman nuttall */
#define FFT_WIN_TYP_BLACKMAN_HARRIS \
FFTWindow::Blackman_Harris /* blackman harris*/
#define FFT_WIN_TYP_FLT_TOP FFTWindow::Flat_top /* flat top */
#define FFT_WIN_TYP_WELCH FFTWindow::Welch /* welch */
/* End of compatibility defines */
/* Mathematial constants */
#define twoPi 6.28318531
#define fourPi 12.56637061
#define sixPi 18.84955593
enum class FFTWindow {
Rectangle, // rectangle (Box car)
Hamming, // hamming
Hann, // hann
Triangle, // triangle (Bartlett)
Nuttall, // nuttall
Blackman, // blackman
Blackman_Nuttall, // blackman nuttall
Blackman_Harris, // blackman harris
Flat_top, // flat top
Welch, // welch
Precompiled // Placeholder for using custom or precompiled window values
};
enum class FFTDirection { Forward, Reverse };
#endif

Wyświetl plik

@ -19,17 +19,21 @@ typedef signed long s32;
typedef unsigned long long u64;
typedef signed long long s64;
/* use inttypes.h instead
// C99 standard integer type definitions
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned long uint32_t;
typedef signed long int32_t;
typedef unsigned long uint64_t;
typedef signed long int64_t;
*/
// #ifndef __AVR__
#ifdef __MBED__
// use inttypes.h instead
// C99 standard integer type definitions
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
/*typedef unsigned long uint32_t;
typedef signed long int32_t;
typedef unsigned long uint64_t;
typedef signed long int64_t;
*/
#endif
// maximum value that can be held
// by unsigned data types (8,16,32bits)
#define MAX_U08 255