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!" << std::endl;
103 if( !file.is_open() ){
104 errorLog <<
"saveModelToFile(fstream &file) - The file is not open!" << std::endl;
109 file <<
"GRT_FFT_FILE_V1.0" << std::endl;
113 errorLog <<
"saveFeatureExtractionSettingsToFile(fstream &file) - Failed to save base feature extraction settings to file!" << std::endl;
118 file <<
"HopSize: " <<
hopSize << std::endl;
129 if( !file.is_open() ){
130 errorLog <<
"loadModelFromFile(fstream &file) - The file is not open!" << std::endl;
139 if( word !=
"GRT_FFT_FILE_V1.0" ){
140 errorLog <<
"loadModelFromFile(fstream &file) - Invalid file format!" << std::endl;
145 errorLog <<
"loadFeatureExtractionSettingsFromFile(fstream &file) - Failed to load base feature extraction settings from file!" << std::endl;
150 if( word !=
"HopSize:" ){
151 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read HopSize header!" << std::endl;
157 if( word !=
"FftWindowSize:" ){
158 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read FftWindowSize header!" << std::endl;
164 if( word !=
"FftWindowFunction:" ){
165 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read FftWindowFunction header!" << std::endl;
171 if( word !=
"ComputeMagnitude:" ){
172 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read ComputeMagnitude header!" << std::endl;
178 if( word !=
"ComputePhase:" ){
179 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read ComputePhase header!" << std::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,DataType inputType,DataType outputType){
194 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - fftWindowSize is not a power of two!" << std::endl;
198 if( !validateFFTWindowFunction( fftWindowFunction ) ){
199 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - Unkown Window Function!" << std::endl;
209 this->inputType = inputType;
210 this->outputType = outputType;
212 featureDataReady =
false;
213 numInputDimensions = numDimensions;
216 numOutputDimensions = 0;
217 if( computePhase ) numOutputDimensions += fftWindowSize/2 * numInputDimensions;
218 if( computeMagnitude ) numOutputDimensions += fftWindowSize/2 * numInputDimensions;
221 featureVector.
resize( numOutputDimensions, 0);
236 for(
unsigned int i=0; i<numInputDimensions; i++){
237 if( !
fft[i].
init(fftWindowSize,fftWindowFunction,computeMagnitude,computePhase) ){
238 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - Failed to initialize fft!" << std::endl;
250 return update( inputVector );
254 return update( inputMatrix );
260 errorLog <<
"update(const Float x) - Not initialized!" << std::endl;
264 if( numInputDimensions != 1 ){
265 errorLog <<
"update(const Float x) - The size of the input (1) does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
275 errorLog <<
"update(const VectorFloat &x) - Not initialized!" << std::endl;
279 if( x.size() != numInputDimensions ){
280 errorLog <<
"update(const VectorFloat &x) - The size of the input (" << x.size() <<
") does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
287 featureDataReady =
false;
292 for(UINT j=0; j<numInputDimensions; j++){
301 errorLog <<
"update(const VectorFloat &x) - Failed to compute FFT!" << std::endl;
307 featureDataReady =
true;
311 for(UINT j=0; j<numInputDimensions; j++){
313 Float *mag =
fft[j].getMagnitudeDataPtr();
314 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
315 featureVector[index++] = *mag++;
319 Float *phase =
fft[j].getPhaseDataPtr();
320 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
321 featureVector[index++] = *phase++;
333 errorLog <<
"update(const MatrixFloat &x) - Not initialized!" << std::endl;
338 errorLog <<
"update(const MatrixFloat &x) - The number of columns in the inputMatrix (" << x.
getNumCols() <<
") does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
342 featureDataReady =
false;
352 for(UINT j=0; j<numInputDimensions; j++){
361 errorLog <<
"update(const VectorFloat &x) - Failed to compute FFT!" << std::endl;
367 featureDataReady =
true;
371 for(UINT j=0; j<numInputDimensions; j++){
373 Float *mag =
fft[j].getMagnitudeDataPtr();
374 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
375 featureVector[index++] = *mag++;
379 Float *phase =
fft[j].getPhaseDataPtr();
380 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
381 featureVector[index++] = *phase++;
410 if(initialized){
return hopSize; }
421 if( !initialized )
return 0;
435 VectorFloat FFT::getFrequencyBins(
const unsigned int sampleRate){
440 freqBins[i] = (i*sampleRate) / fftWindowSize;
451 errorLog <<
"setHopSize(UINT hopSize) - The hopSize value must be greater than zero!" << std::endl;
461 errorLog <<
"setFFTWindowSize(UINT fftWindowSize) - fftWindowSize must be a power of two!" << std::endl;
467 if( validateFFTWindowFunction( fftWindowFunction ) ){
488 if (x < 2)
return false;
489 if (x & (x - 1))
return false;
493 bool FFT::validateFFTWindowFunction(UINT fftWindowFunction){
494 if( fftWindowFunction != RECTANGULAR_WINDOW && fftWindowFunction != BARTLETT_WINDOW &&
495 fftWindowFunction != HAMMING_WINDOW && fftWindowFunction != HANNING_WINDOW ){
bool push_back(const T &value)
UINT dataBufferSize
Stores how much previous input data is stored in the dataBuffer.
Vector< FastFourierTransform > fft
A buffer used to store the FFT results.
CircularBuffer< VectorFloat > dataBuffer
A circular buffer used to store the previous M inputs.
UINT fftWindowFunction
The current windowFunction used for the FFT.
bool setHopSize(UINT hopSize)
bool computePhase
Tracks if the phase of the FFT needs to be computed.
UINT hopSize
The current hopSize, this sets how often the fft should be computed.
virtual bool resize(const unsigned int size)
UINT hopCounter
Keeps track of how many input samples the FFT has seen.
VectorFloat tempBuffer
A temporary buffer used to store the input data for the FFT.
bool setComputeMagnitude(bool computeMagnitude)
std::map< unsigned int, unsigned int > windowSizeMap
A map to relate the FFTWindowSize enumerations to actual values.
UINT getFFTWindowFunction()
virtual bool loadModelFromFile(std::fstream &file)
UINT fftWindowSize
Stores the size of the fft (and also the dataBuffer)
FFT(UINT fftWindowSize=512, UINT hopSize=1, UINT numDimensions=1, UINT fftWindowFunction=RECTANGULAR_WINDOW, bool computeMagnitude=true, bool computePhase=true)
unsigned int getNumRows() const
unsigned int getNumCols() const
The FFT class computes the Fourier transform of an N dimensional signal using a Fast Fourier Transfor...
virtual bool deepCopyFrom(const FeatureExtraction *featureExtraction)
bool setFFTWindowFunction(UINT fftWindowFunction)
VectorFloat getRow(const unsigned int r) const
bool setFFTWindowSize(UINT fftWindowSize)
bool setComputePhase(bool computePhase)
virtual bool computeFeatures(const VectorFloat &inputVector)
bool computeMagnitude
Tracks if the magnitude (and power) of the FFT need to be computed.
virtual bool saveModelToFile(std::fstream &file) const
FFT & operator=(const FFT &rhs)
bool isPowerOfTwo(UINT x)
A helper function to compute if the input is a power of two.
bool update(const Float x)
bool resize(const unsigned int newBufferSize)