26 RegisterFeatureExtractionModule< FFT > FFT::registerModule(
"FFT");
28 FFT::FFT(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,
bool computeMagnitude,
bool computePhase){
31 featureExtractionType = classType;
34 featureDataReady =
false;
35 numInputDimensions = 0;
36 numOutputDimensions = 0;
38 infoLog.setProceedingText(
"[FFT]");
39 warningLog.setProceedingText(
"[WARNING FFT]");
40 errorLog.setProceedingText(
"[ERROR FFT]");
42 if(
isPowerOfTwo(fftWindowSize) && hopSize > 0 && numDimensions > 0 ){
43 init(fftWindowSize,hopSize,numDimensions,fftWindowFunction,computeMagnitude,computePhase);
48 infoLog.setProceedingText(
"[FFT]");
49 warningLog.setProceedingText(
"[WARNING FFT]");
50 errorLog.setProceedingText(
"[ERROR FFT]");
86 if( featureExtraction == NULL )
return false;
91 *
this = *(
FFT*)featureExtraction;
96 errorLog <<
"clone(FeatureExtraction *featureExtraction) - FeatureExtraction Types Do Not Match!" << endl;
103 if( !file.is_open() ){
104 errorLog <<
"saveModelToFile(fstream &file) - The file is not open!" << endl;
109 file <<
"GRT_FFT_FILE_V1.0" << endl;
113 errorLog <<
"saveFeatureExtractionSettingsToFile(fstream &file) - Failed to save base feature extraction settings to file!" << endl;
118 file <<
"HopSize: " <<
hopSize << endl;
129 if( !file.is_open() ){
130 errorLog <<
"loadModelFromFile(fstream &file) - The file is not open!" << endl;
139 if( word !=
"GRT_FFT_FILE_V1.0" ){
140 errorLog <<
"loadModelFromFile(fstream &file) - Invalid file format!" << endl;
145 errorLog <<
"loadFeatureExtractionSettingsFromFile(fstream &file) - Failed to load base feature extraction settings from file!" << endl;
150 if( word !=
"HopSize:" ){
151 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read HopSize header!" << endl;
157 if( word !=
"FftWindowSize:" ){
158 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read FftWindowSize header!" << endl;
164 if( word !=
"FftWindowFunction:" ){
165 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read FftWindowFunction header!" << endl;
171 if( word !=
"ComputeMagnitude:" ){
172 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read ComputeMagnitude header!" << endl;
178 if( word !=
"ComputePhase:" ){
179 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read ComputePhase header!" << endl;
185 return init(fftWindowSize,hopSize,numInputDimensions,fftWindowFunction,computeMagnitude,computePhase);
188 bool FFT::init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,
bool computeMagnitude,
bool computePhase){
194 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - fftWindowSize is not a power of two!" << endl;
198 if( !validateFFTWindowFunction( fftWindowFunction ) ){
199 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - Unkown Window Function!" << endl;
210 featureDataReady =
false;
211 numInputDimensions = numDimensions;
214 numOutputDimensions = 0;
215 if( computePhase ) numOutputDimensions += fftWindowSize/2 * numInputDimensions;
216 if( computeMagnitude ) numOutputDimensions += fftWindowSize/2 * numInputDimensions;
219 featureVector.resize( numOutputDimensions, 0);
233 fft.resize(numInputDimensions);
234 for(
unsigned int i=0; i<numInputDimensions; i++){
235 if( !
fft[i].
init(fftWindowSize,fftWindowFunction,computeMagnitude,computePhase) ){
236 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - Failed to initialize fft!" << endl;
250 errorLog <<
"computeFeatures(const VectorDouble &inputVector) - Not initialized!" << endl;
254 if( inputVector.size() != numInputDimensions ){
255 errorLog <<
"computeFeatures(const VectorDouble &inputVector) - The size of the inputVector (" << inputVector.size() <<
") does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << endl;
259 return update(inputVector);
265 errorLog <<
"update(const double x) - Not initialized!" << endl;
269 if( numInputDimensions != 1 ){
270 errorLog <<
"update(const double x) - The size of the input (1) does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << endl;
274 return update(VectorDouble(1,x));
280 errorLog <<
"update(const VectorDouble &x) - Not initialized!" << endl;
284 if( x.size() != numInputDimensions ){
285 errorLog <<
"update(const VectorDouble &x) - The size of the input (" << x.size() <<
") does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << endl;
292 featureDataReady =
false;
297 for(UINT j=0; j<numInputDimensions; j++){
306 errorLog <<
"update(const VectorDouble &x) - Failed to compute FFT!" << endl;
312 featureDataReady =
true;
316 for(UINT j=0; j<numInputDimensions; j++){
318 double *mag =
fft[j].getMagnitudeDataPtr();
319 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
320 featureVector[index++] = *mag++;
324 double *phase =
fft[j].getPhaseDataPtr();
325 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
326 featureVector[index++] = *phase++;
354 if(initialized){
return hopSize; }
365 if( !initialized )
return 0;
379 VectorDouble FFT::getFrequencyBins(
const unsigned int sampleRate){
380 if( !initialized ){
return VectorDouble(); }
384 freqBins[i] = (i*sampleRate) / fftWindowSize;
395 errorLog <<
"setHopSize(UINT hopSize) - The hopSize value must be greater than zero!" << endl;
405 errorLog <<
"setFFTWindowSize(UINT fftWindowSize) - fftWindowSize must be a power of two!" << endl;
411 if( validateFFTWindowFunction( fftWindowFunction ) ){
432 if (x < 2)
return false;
433 if (x & (x - 1))
return false;
437 bool FFT::validateFFTWindowFunction(UINT fftWindowFunction){
438 if( fftWindowFunction != RECTANGULAR_WINDOW && fftWindowFunction != BARTLETT_WINDOW &&
439 fftWindowFunction != HAMMING_WINDOW && fftWindowFunction != HANNING_WINDOW ){
GRT::VectorDouble tempBuffer
A temporary buffer used to store the input data for the FFT.
bool setFFTWindowFunction(UINT fftWindowFunction)
virtual bool saveModelToFile(fstream &file) const
UINT hopSize
The current hopSize, this sets how often the fft should be computed.
FFT(UINT fftWindowSize=512, UINT hopSize=1, UINT numDimensions=1, UINT fftWindowFunction=RECTANGULAR_WINDOW, bool computeMagnitude=true, bool computePhase=true)
UINT dataBufferSize
Stores how much previous input data is stored in the dataBuffer.
virtual bool computeFeatures(const VectorDouble &inputVector)
virtual bool deepCopyFrom(const FeatureExtraction *featureExtraction)
bool computePhase
Tracks if the phase of the FFT needs to be computed.
bool setComputeMagnitude(bool computeMagnitude)
bool push_back(const T &value)
FFT & operator=(const FFT &rhs)
UINT fftWindowSize
Stores the size of the fft (and also the dataBuffer)
bool computeMagnitude
Tracks if the magnitude (and power) of the FFT need to be computed.
bool setFFTWindowSize(UINT fftWindowSize)
vector< FastFourierTransform > fft
A buffer used to store the FFT results.
bool resize(const unsigned int newBufferSize)
CircularBuffer< VectorDouble > dataBuffer
A circular buffer used to store the previous M inputs.
bool update(const double x)
UINT getFFTWindowFunction()
bool isPowerOfTwo(UINT x)
A helper function to compute if the input is a power of two.
std::map< unsigned int, unsigned int > windowSizeMap
A map to relate the FFTWindowSize enumerations to actual values.
The FFT class computes the Fourier transform of an N dimensional signal using a Fast Fourier Transfor...
bool setHopSize(UINT hopSize)
bool setComputePhase(bool computePhase)
UINT fftWindowFunction
The current windowFunction used for the FFT.
virtual bool loadModelFromFile(fstream &file)
UINT hopCounter
Keeps track of how many input samples the FFT has seen.