diff --git a/changeLog.txt b/changeLog.txt index 287cbb6..da48c90 100644 --- a/changeLog.txt +++ b/changeLog.txt @@ -1,3 +1,6 @@ +01/24/20 v1.5.5 +Lookup table for constants c1 and c2 used during FFT comupting. This increases the FFT computing speed in around 5%. + 02/10/18 v1.4 Transition version. Minor optimization to functions. New API. Deprecation of old functions. diff --git a/library.json b/library.json index c855f70..32c7606 100644 --- a/library.json +++ b/library.json @@ -20,7 +20,7 @@ "email": "contact@arduinoos.com" } ], - "version": "1.5", + "version": "1.5.5", "frameworks": ["arduino","mbed","espidf"], "platforms": "*" } diff --git a/library.properties b/library.properties index 044de0f..cd86480 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=arduinoFFT -version=1.5 +version=1.5.5 author=Enrique Condes maintainer=Enrique Condes sentence=A library for implementing floating point Fast Fourier Transform calculations on Arduino. diff --git a/src/arduinoFFT.cpp b/src/arduinoFFT.cpp index 2f10d04..f552fc9 100644 --- a/src/arduinoFFT.cpp +++ b/src/arduinoFFT.cpp @@ -23,7 +23,7 @@ arduinoFFT::arduinoFFT(void) { // Constructor - #warning("This method is deprecated and will be removed on future revisions.") + #warning("This method is deprecated and may be removed on future revisions.") } arduinoFFT::arduinoFFT(double *vReal, double *vImag, uint16_t samples, double samplingFrequency) @@ -47,7 +47,7 @@ uint8_t arduinoFFT::Revision(void) void arduinoFFT::Compute(double *vReal, double *vImag, uint16_t samples, uint8_t dir) { - #warning("This method is deprecated and will be removed on future revisions.") + #warning("This method is deprecated and may be removed on future revisions.") Compute(vReal, vImag, samples, Exponent(samples), dir); } @@ -69,6 +69,9 @@ void arduinoFFT::Compute(uint8_t dir) j += k; } // Compute the FFT / +#ifdef __AVR__ + uint8_t index = 0; +#endif double c1 = -1.0; double c2 = 0.0; uint16_t l2 = 1; @@ -91,11 +94,17 @@ void arduinoFFT::Compute(uint8_t dir) u2 = ((u1 * c2) + (u2 * c1)); u1 = z; } +#ifdef __AVR__ + c2 = pgm_read_float_near(&(_c2[index])); + c1 = pgm_read_float_near(&(_c1[index])); + index++; +#else c2 = sqrt((1.0 - c1) / 2.0); + c1 = sqrt((1.0 + c1) / 2.0); +#endif if (dir == FFT_FORWARD) { c2 = -c2; } - c1 = sqrt((1.0 + c1) / 2.0); } // Scaling for reverse transform / if (dir != FFT_FORWARD) { @@ -109,7 +118,7 @@ void arduinoFFT::Compute(uint8_t dir) 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 - #warning("This method is deprecated and will be removed on future revisions.") + #warning("This method is deprecated and may be removed on future revisions.") uint16_t j = 0; for (uint16_t i = 0; i < (samples - 1); i++) { if (i < j) { @@ -125,6 +134,9 @@ void arduinoFFT::Compute(double *vReal, double *vImag, uint16_t samples, uint8_t j += k; } // Compute the FFT +#ifdef __AVR__ + uint8_t index = 0; +#endif double c1 = -1.0; double c2 = 0.0; uint16_t l2 = 1; @@ -147,11 +159,17 @@ void arduinoFFT::Compute(double *vReal, double *vImag, uint16_t samples, uint8_t u2 = ((u1 * c2) + (u2 * c1)); u1 = z; } +#ifdef __AVR__ + c2 = pgm_read_float_near(&(_c2[index])); + c1 = pgm_read_float_near(&(_c1[index])); + index++; +#else c2 = sqrt((1.0 - c1) / 2.0); + c1 = sqrt((1.0 + c1) / 2.0); +#endif if (dir == FFT_FORWARD) { c2 = -c2; } - c1 = sqrt((1.0 + c1) / 2.0); } // Scaling for reverse transform if (dir != FFT_FORWARD) { @@ -171,7 +189,7 @@ void arduinoFFT::ComplexToMagnitude() void arduinoFFT::ComplexToMagnitude(double *vReal, double *vImag, uint16_t samples) { // vM is half the size of vReal and vImag - #warning("This method is deprecated and will be removed on future revisions.") + #warning("This method is deprecated and may be removed on future revisions.") for (uint16_t i = 0; i < samples; i++) { vReal[i] = sqrt(sq(vReal[i]) + sq(vImag[i])); } @@ -196,7 +214,7 @@ void arduinoFFT::DCRemoval() void arduinoFFT::DCRemoval(double *vData, uint16_t samples) { // calculate the mean of vData - #warning("This method is deprecated and will be removed on future revisions.") + #warning("This method is deprecated and may be removed on future revisions.") double mean = 0; for (uint16_t i = 1; i < ((samples >> 1) + 1); i++) { @@ -266,7 +284,7 @@ void arduinoFFT::Windowing(uint8_t windowType, uint8_t 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 - #warning("This method is deprecated and will be removed on future revisions.") + #warning("This method is deprecated and may be removed on future revisions.") double samplesMinusOne = (double(samples) - 1.0); for (uint16_t i = 0; i < (samples >> 1); i++) { double indexMinusOne = double(i); @@ -363,7 +381,7 @@ void arduinoFFT::MajorPeak(double *f, double *v) double arduinoFFT::MajorPeak(double *vD, uint16_t samples, double samplingFrequency) { - #warning("This method is deprecated and will be removed on future revisions.") + #warning("This method is deprecated and may be removed on future revisions.") double maxY = 0; uint16_t IndexOfMaxY = 0; //If sampling_frequency = 2 * max_frequency in signal, @@ -386,7 +404,7 @@ double arduinoFFT::MajorPeak(double *vD, uint16_t samples, double samplingFreque void arduinoFFT::MajorPeak(double *vD, uint16_t samples, double samplingFrequency, double *f, double *v) { - #warning("This method is deprecated and will be removed on future revisions.") + #warning("This method is deprecated and may be removed on future revisions.") double maxY = 0; uint16_t IndexOfMaxY = 0; //If sampling_frequency = 2 * max_frequency in signal, @@ -411,7 +429,7 @@ void arduinoFFT::MajorPeak(double *vD, uint16_t samples, double samplingFrequenc uint8_t arduinoFFT::Exponent(uint16_t value) { - #warning("This method will not be accessible on future revisions.") + #warning("This method may not be accessible on future revisions.") // Calculates the base 2 logarithm of a value uint8_t result = 0; while (((value >> result) & 1) != 1) result++; diff --git a/src/arduinoFFT.h b/src/arduinoFFT.h index 2324e72..73927dc 100644 --- a/src/arduinoFFT.h +++ b/src/arduinoFFT.h @@ -32,6 +32,7 @@ #include #ifdef __AVR__ #include + #include #endif #include #include "defs.h" @@ -59,6 +60,18 @@ #define fourPi 12.56637061 #define sixPi 18.84955593 +#ifdef __AVR__ + static const double _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 double _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 class arduinoFFT { public: /* Constructor */ @@ -69,21 +82,21 @@ public: /* Functions */ uint8_t Revision(void); uint8_t Exponent(uint16_t value); + 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); void DCRemoval(double *vData, uint16_t samples); double MajorPeak(double *vD, uint16_t samples, double samplingFrequency); + void MajorPeak(double *vD, uint16_t samples, double samplingFrequency, double *f, double *v); void Windowing(double *vData, uint16_t samples, uint8_t windowType, uint8_t dir); + void ComplexToMagnitude(); void Compute(uint8_t dir); void DCRemoval(); double MajorPeak(); - void Windowing(uint8_t windowType, uint8_t dir); - void MajorPeak(double *f, double *v); - void MajorPeak(double *vD, uint16_t samples, double samplingFrequency, double *f, double *v); - + void Windowing(uint8_t windowType, uint8_t dir); private: /* Variables */