From 4a36bd2453b2e783d810f71e20c7695631a6ab06 Mon Sep 17 00:00:00 2001 From: Bim Overbohm Date: Sat, 22 Feb 2020 13:35:09 +0100 Subject: [PATCH] Add setArrays() function because of issue #32. Add API migration info to README and improve README. --- README.md | 88 ++++++++++++++++++++++++++++++++-------------- changeLog.txt | 7 +++- keywords.txt | 1 + library.json | 2 +- library.properties | 2 +- src/arduinoFFT.h | 13 +++++-- 6 files changed, 81 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index fe000f6..d801455 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 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.~~ Now it works both on Arduino and C projects. +~~This is a C++ library for Arduino for computing FFT.~~ Now it works both on Arduino and C projects. This is version 2.0 of the library, which has a different [API](#api). See here [how to migrate from 1.x to 2.x](#migrating-from-1.x-to-2.x). Tested on Arduino 1.6.11 and 1.8.10. ## Installation on Arduino @@ -16,49 +16,57 @@ Use the Arduino Library Manager to install and keep it updated. Just look for ar To install this library, just place this entire folder as a subfolder in your Arduino installation. When installed, this library should look like: `Arduino\libraries\arduinoFTT` (this library's folder) -`Arduino\libraries\arduinoFTT\arduinoFTT.h` (the library header file, uses 32 bit floats or 64bit doubles) +`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\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. - +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 ` -## TODO -* Ratio table for windowing function. -* Document windowing functions advantages and disadvantages. -* Optimize usage and arguments. -* Add new windowing functions. -* ~~Spectrum table?~~ - ## API -* **ArduinoFFT**(T *vReal, T *vImag, uint_fast16_t samples, T samplingFrequency, T * weighingFactors = nullptr); +* ```ArduinoFFT(T *vReal, T *vImag, uint_fast16_t samples, T samplingFrequency, T * weighingFactors = nullptr);``` Constructor. -The type `T` can be `float` or `double`. `vReal` and `vImag` are pointers to arrays of real and imaginary data and have to be allocated outside of ArduinoFFT. `samples` is the number of samples in `vReal` and `vImag` and `weighingFactors` (if specified). `samplingFrequency` is the sample frequency of the data. `weighingFactors` can optionally be specified to cache weighing factors for the windowing function. This speeds up repeated calls to **windowing()** significantly. +The type `T` can be `float` or `double`. `vReal` and `vImag` are pointers to arrays of real and imaginary data and have to be allocated outside of ArduinoFFT. `samples` is the number of samples in `vReal` and `vImag` and `weighingFactors` (if specified). `samplingFrequency` is the sample frequency of the data. `weighingFactors` can optionally be specified to cache weighing factors for the windowing function. This speeds up repeated calls to **windowing()** significantly. You can deallocate `vReal` and `vImag` after you are done using the library, or only use specific library functions that only need one of those arrays. -* **~ArduinoFFT**(void); +```C++ +const uint32_t nrOfSamples = 1024; +auto real = new float[nrOfSamples]; +auto imag = new float[nrOfSamples]; +auto fft = ArduinoFFT(real, imag, nrOfSamples, 10000); +// ... fill real + imag and use it ... +fft.compute(); +fft.complexToMagnitude(); +delete [] imag; +// ... continue using real and only functions that use real ... +auto peak = fft.majorPeak(); +``` +* ```~ArduinoFFT()``` Destructor. -* **complexToMagnitude**(); -Convert complex values to their magnitude and store in vReal. -* **compute**(FFTDirection dir); -Calcuates the Fast Fourier Transform. -* **dcRemoval**(); -Removes the DC component from the sample data. -* **majorPeak**(); -Looks for and returns the frequency of the biggest spike in the analyzed signal. -* **revision**(); +* ```void complexToMagnitude() const;``` +Convert complex values to their magnitude and store in vReal. Uses vReal and vImag. +* ```void compute(FFTDirection dir) const;``` +Calcuates the Fast Fourier Transform. Uses vReal and vImag. +* ```void dcRemoval() const;``` +Removes the DC component from the sample data. Uses vReal. +* ```T majorPeak() const;``` +Returns the frequency of the biggest spike in the analyzed signal. Uses vReal. +* ```void majorPeak(T &frequency, T &value) const;``` +Returns the frequency and the value of the biggest spike in the analyzed signal. Uses vReal. +* ```uint8_t revision() const;``` Returns the library revision. -* **windowing**(FFTWindow windowType, FFTDirection dir, bool withCompensation = false); -Performs a windowing function on the values array. The possible windowing options are: +* ```void setArrays(T *vReal, T *vImag);``` +Replace the data array pointers. +* ```void windowing(FFTWindow windowType, FFTDirection dir, bool withCompensation = false);``` +Performs a windowing function on the values array. Uses vReal. The possible windowing options are: * Rectangle * Hamming * Hann @@ -91,3 +99,31 @@ Define this to use reciprocal multiplication for division and some more speedups * #define FFT_SQRT_APPROXIMATION 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 if `T == float`. + +See the `FFT_speedup.ino` example in `Examples/FFT_speedup/FFT_speedup.ino`. + +# Migrating from 1.x to 2.x + +* The function signatures where you could pass in pointers were deprecated and have been removed. Pass in pointers to your real / imaginary array in the ArduinoFFT() constructor. If you have the need to replace those pointers during usage of the library (e.g. to free memory) you can do the following: + +```C++ +const uint32_t nrOfSamples = 1024; +auto real = new float[nrOfSamples]; +auto imag = new float[nrOfSamples]; +auto fft = ArduinoFFT(real, imag, nrOfSamples, 10000); +// ... fill real + imag and use it ... +fft.compute(); +fft.complexToMagnitude(); +delete [] real; +// ... replace vReal in library with imag ... +fft.setArrays(imag, nullptr); +// ... keep doin whatever ... +``` +* All function names are camelCase case now (start with lower-case character), e.g. "windowing()" instead of "Windowing()". + +## TODO +* Ratio table for windowing function. +* Document windowing functions advantages and disadvantages. +* Optimize usage and arguments. +* Add new windowing functions. +* ~~Spectrum table?~~ \ No newline at end of file diff --git a/changeLog.txt b/changeLog.txt index b6dc9ad..1888af9 100644 --- a/changeLog.txt +++ b/changeLog.txt @@ -1,8 +1,13 @@ +02/22/20 v1.9.1 +Add setArrays() function because of issue #32. +Add API migration info to README and improve README. +Use better sqrtf() approximation. + 02/19/20 v1.9.0 Remove deprecated API. Consistent renaming of functions to lowercase. Make template to be able to use float or double type (float brings a ~70% speed increase on ESP32). Add option to provide cache for window function weighing factors (~50% speed increase on ESP32). -Add some #defines to enable math approximisations to further speed up code (~50% speed increase on ESP32). +Add some #defines to enable math approximisations to further speed up code (~40% speed increase on ESP32). 01/27/20 v1.5.5 Lookup table for constants c1 and c2 used during FFT comupting. This increases the FFT computing speed in around 5%. diff --git a/keywords.txt b/keywords.txt index c0f1804..3807cdb 100644 --- a/keywords.txt +++ b/keywords.txt @@ -21,6 +21,7 @@ windowing KEYWORD2 exponent KEYWORD2 revision KEYWORD2 majorPeak KEYWORD2 +setArrays KEYWORD2 ####################################### # Constants (LITERAL1) diff --git a/library.json b/library.json index e3b8371..a849eb9 100644 --- a/library.json +++ b/library.json @@ -25,7 +25,7 @@ "email": "bim.overbohm@googlemail.com" } ], - "version": "1.9.0", + "version": "1.9.1", "frameworks": ["arduino","mbed","espidf"], "platforms": "*" } diff --git a/library.properties b/library.properties index 986fbe3..0ee368b 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=arduinoFFT -version=1.9.0 +version=1.9.1 author=Enrique Condes maintainer=Enrique Condes sentence=A library for implementing floating point Fast Fourier Transform calculations on Arduino. diff --git a/src/arduinoFFT.h b/src/arduinoFFT.h index 564df15..2dc39fb 100644 --- a/src/arduinoFFT.h +++ b/src/arduinoFFT.h @@ -106,6 +106,13 @@ public: return 0x19; } + // Replace the data array pointers + void setArrays(T *vReal, T *vImag) + { + _vReal = vReal; + _vImag = vImag; + } + // Computes in-place complex-to-complex FFT void compute(FFTDirection dir) const { @@ -347,7 +354,7 @@ public: return interpolatedX; } - void majorPeak(T &f, T &v) const + void majorPeak(T &frequency, T &value) const { T maxY = 0; uint_fast16_t IndexOfMaxY = 0; @@ -372,8 +379,8 @@ public: interpolatedX = ((IndexOfMaxY + delta) * this->_samplingFrequency) / (this->_samples); } // returned value: interpolated frequency peak apex - f = interpolatedX; - v = abs(this->_vReal[IndexOfMaxY - 1] - (2.0 * this->_vReal[IndexOfMaxY]) + this->_vReal[IndexOfMaxY + 1]); + frequency = interpolatedX; + value = abs(this->_vReal[IndexOfMaxY - 1] - (2.0 * this->_vReal[IndexOfMaxY]) + this->_vReal[IndexOfMaxY + 1]); } private: