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);
Destructor.
* **complexToMagnitude**();
Convert complex values to their magnitude and store in vReal.
Convert complex values to their magnitude and store in vReal.
* **compute**(FFTDirection dir);
Calcuates the Fast Fourier Transform.
* **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.
* **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:
* Rectangle
* Hamming
@ -66,10 +66,22 @@ Performs a windowing function on the values array. The possible windowing option
* Nuttall
* Blackman
* Blackman_Nuttall
* Blackman_Harris
* Blackman_Harris
* Flat_top
* 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
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
if (_windowWeighingFactors && weighingFactorsComputed && weighingFactorsFFTWindow == windowType)
// check if values are already pre-computed for the correct window type and compensation
if (_windowWeighingFactors && _weighingFactorsComputed &&
_weighingFactorsFFTWindow == windowType &&
_weighingFactorsWithCompensation == withCompensation)
{
// yes. values are precomputed
if (dir == FFTDirection::Forward)
@ -242,6 +244,7 @@ public:
{
// no. values need to be pre-computed or applied
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++)
{
T indexMinusOne = T(i);
@ -281,6 +284,10 @@ public:
weighingFactor = 1.0 - sq((indexMinusOne - samplesMinusOne / 2.0) / (samplesMinusOne / 2.0));
break;
}
if (withCompensation)
{
weighingFactor *= compensationFactor;
}
if (_windowWeighingFactors)
{
_windowWeighingFactors[i] = weighingFactor;
@ -304,8 +311,9 @@ public:
}
}
// mark cached values as pre-computed
weighingFactorsFFTWindow = windowType;
weighingFactorsComputed = true;
_weighingFactorsFFTWindow = windowType;
_weighingFactorsWithCompensation = withCompensation;
_weighingFactorsComputed = true;
}
}
@ -381,6 +389,18 @@ private:
0.0003834952, 0.0001917476, 0.0000958738, 0.0000479369,
0.0000239684};
#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
#ifndef TWO_PI
@ -431,8 +451,9 @@ private:
T *_vReal = nullptr;
T *_vImag = nullptr;
T * _windowWeighingFactors = nullptr;
FFTWindow weighingFactorsFFTWindow;
bool weighingFactorsComputed = false;
FFTWindow _weighingFactorsFFTWindow;
bool _weighingFactorsWithCompensation = false;
bool _weighingFactorsComputed = false;
uint_fast8_t _power = 0;
};