Add windowing compensation factors

pull/42/head
Bim Overbohm 2020-02-19 18:06:11 +01:00
rodzic 08e9288cc9
commit 49bc726738
2 zmienionych plików z 43 dodań i 10 usunięć

Wyświetl plik

@ -48,7 +48,7 @@ The type `T` can be `float` or `double`. `vReal` and `vImag` are pointers to arr
* **~ArduinoFFT**(void); * **~ArduinoFFT**(void);
Destructor. Destructor.
* **complexToMagnitude**(); * **complexToMagnitude**();
Convert complex values to their magnitude and store in vReal. Convert complex values to their magnitude and store in vReal.
* **compute**(FFTDirection dir); * **compute**(FFTDirection dir);
Calcuates the Fast Fourier Transform. Calcuates the Fast Fourier Transform.
* **dcRemoval**(); * **dcRemoval**();
@ -57,7 +57,7 @@ Removes the DC component from the sample data.
Looks for and returns the frequency of the biggest spike in the analyzed signal. Looks for and returns the frequency of the biggest spike in the analyzed signal.
* **revision**(); * **revision**();
Returns the library revision. Returns the library revision.
* **windowing**(FFTWindow windowType, FFTDirection dir); * **windowing**(FFTWindow windowType, FFTDirection dir, bool withCompensation = false);
Performs a windowing function on the values array. The possible windowing options are: Performs a windowing function on the values array. The possible windowing options are:
* Rectangle * Rectangle
* Hamming * Hamming
@ -66,10 +66,22 @@ Performs a windowing function on the values array. The possible windowing option
* Nuttall * Nuttall
* Blackman * Blackman
* Blackman_Nuttall * Blackman_Nuttall
* Blackman_Harris * Blackman_Harris
* Flat_top * Flat_top
* Welch * Welch
If `withCompensation` == true, the following compensation factors are used:
* Rectangle: 1.0 * 2.0
* Hamming: 1.8549343278 * 2.0
* Hann: 1.8554726898 * 2.0
* Triangle: 2.0039186079 * 2.0
* Nuttall: 2.8163172034 * 2.0
* Blackman: 2.3673474360 * 2.0
* Blackman Nuttall: 2.7557840395 * 2.0
* Blackman Harris: 2.7929062517 * 2.0
* Flat top: 3.5659039231 * 2.0
* Welch: 1.5029392863 * 2.0
## Special flags ## Special flags
You can define these before including arduinoFFT.h: You can define these before including arduinoFFT.h:

Wyświetl plik

@ -208,10 +208,12 @@ public:
} }
} }
void windowing(FFTWindow windowType, FFTDirection dir) void windowing(FFTWindow windowType, FFTDirection dir, bool withCompensation = false)
{ {
// check if values are already pre-computed for the correct window type // check if values are already pre-computed for the correct window type and compensation
if (_windowWeighingFactors && weighingFactorsComputed && weighingFactorsFFTWindow == windowType) if (_windowWeighingFactors && _weighingFactorsComputed &&
_weighingFactorsFFTWindow == windowType &&
_weighingFactorsWithCompensation == withCompensation)
{ {
// yes. values are precomputed // yes. values are precomputed
if (dir == FFTDirection::Forward) if (dir == FFTDirection::Forward)
@ -242,6 +244,7 @@ public:
{ {
// no. values need to be pre-computed or applied // no. values need to be pre-computed or applied
T samplesMinusOne = (T(this->_samples) - 1.0); T samplesMinusOne = (T(this->_samples) - 1.0);
T compensationFactor = _WindowCompensationFactors[static_cast<uint_fast8_t>(windowType)];
for (uint_fast16_t i = 0; i < (this->_samples >> 1); i++) for (uint_fast16_t i = 0; i < (this->_samples >> 1); i++)
{ {
T indexMinusOne = T(i); T indexMinusOne = T(i);
@ -281,6 +284,10 @@ public:
weighingFactor = 1.0 - sq((indexMinusOne - samplesMinusOne / 2.0) / (samplesMinusOne / 2.0)); weighingFactor = 1.0 - sq((indexMinusOne - samplesMinusOne / 2.0) / (samplesMinusOne / 2.0));
break; break;
} }
if (withCompensation)
{
weighingFactor *= compensationFactor;
}
if (_windowWeighingFactors) if (_windowWeighingFactors)
{ {
_windowWeighingFactors[i] = weighingFactor; _windowWeighingFactors[i] = weighingFactor;
@ -304,8 +311,9 @@ public:
} }
} }
// mark cached values as pre-computed // mark cached values as pre-computed
weighingFactorsFFTWindow = windowType; _weighingFactorsFFTWindow = windowType;
weighingFactorsComputed = true; _weighingFactorsWithCompensation = withCompensation;
_weighingFactorsComputed = true;
} }
} }
@ -381,6 +389,18 @@ private:
0.0003834952, 0.0001917476, 0.0000958738, 0.0000479369, 0.0003834952, 0.0001917476, 0.0000958738, 0.0000479369,
0.0000239684}; 0.0000239684};
#endif #endif
static constexpr T _WindowCompensationFactors[10] = {
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 */
};
// Mathematial constants // Mathematial constants
#ifndef TWO_PI #ifndef TWO_PI
@ -431,8 +451,9 @@ private:
T *_vReal = nullptr; T *_vReal = nullptr;
T *_vImag = nullptr; T *_vImag = nullptr;
T * _windowWeighingFactors = nullptr; T * _windowWeighingFactors = nullptr;
FFTWindow weighingFactorsFFTWindow; FFTWindow _weighingFactorsFFTWindow;
bool weighingFactorsComputed = false; bool _weighingFactorsWithCompensation = false;
bool _weighingFactorsComputed = false;
uint_fast8_t _power = 0; uint_fast8_t _power = 0;
}; };