Lookup table for c1 and c2

pull/49/head
Enrique Condes 2020-01-27 14:27:27 +08:00
rodzic bb4769a44f
commit 852d7466ab
5 zmienionych plików z 51 dodań i 17 usunięć

Wyświetl plik

@ -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.

Wyświetl plik

@ -20,7 +20,7 @@
"email": "contact@arduinoos.com"
}
],
"version": "1.5",
"version": "1.5.5",
"frameworks": ["arduino","mbed","espidf"],
"platforms": "*"
}

Wyświetl plik

@ -1,5 +1,5 @@
name=arduinoFFT
version=1.5
version=1.5.5
author=Enrique Condes <enrique@shapeoko.com>
maintainer=Enrique Condes <enrique@shapeoko.com>
sentence=A library for implementing floating point Fast Fourier Transform calculations on Arduino.

Wyświetl plik

@ -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++;

Wyświetl plik

@ -32,6 +32,7 @@
#include <stdio.h>
#ifdef __AVR__
#include <avr/io.h>
#include <avr/pgmspace.h>
#endif
#include <math.h>
#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 */