21 #define GRT_DLL_EXPORTS
29 FFT::FFT(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,
bool computeMagnitude,
bool computePhase){
32 featureExtractionType = classType;
35 featureDataReady =
false;
36 numInputDimensions = 0;
37 numOutputDimensions = 0;
39 infoLog.setProceedingText(
"[FFT]");
40 warningLog.setProceedingText(
"[WARNING FFT]");
41 errorLog.setProceedingText(
"[ERROR FFT]");
43 if(
isPowerOfTwo(fftWindowSize) && hopSize > 0 && numDimensions > 0 ){
44 init(fftWindowSize,hopSize,numDimensions,fftWindowFunction,computeMagnitude,computePhase);
49 infoLog.setProceedingText(
"[FFT]");
50 warningLog.setProceedingText(
"[WARNING FFT]");
51 errorLog.setProceedingText(
"[ERROR FFT]");
87 if( featureExtraction == NULL )
return false;
92 *
this = *(
FFT*)featureExtraction;
97 errorLog <<
"clone(FeatureExtraction *featureExtraction) - FeatureExtraction Types Do Not Match!" << std::endl;
104 if( !file.is_open() ){
105 errorLog <<
"saveModelToFile(fstream &file) - The file is not open!" << std::endl;
110 file <<
"GRT_FFT_FILE_V1.0" << std::endl;
114 errorLog <<
"saveFeatureExtractionSettingsToFile(fstream &file) - Failed to save base feature extraction settings to file!" << std::endl;
119 file <<
"HopSize: " <<
hopSize << std::endl;
130 if( !file.is_open() ){
131 errorLog <<
"loadModelFromFile(fstream &file) - The file is not open!" << std::endl;
140 if( word !=
"GRT_FFT_FILE_V1.0" ){
141 errorLog <<
"loadModelFromFile(fstream &file) - Invalid file format!" << std::endl;
146 errorLog <<
"loadFeatureExtractionSettingsFromFile(fstream &file) - Failed to load base feature extraction settings from file!" << std::endl;
151 if( word !=
"HopSize:" ){
152 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read HopSize header!" << std::endl;
158 if( word !=
"FftWindowSize:" ){
159 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read FftWindowSize header!" << std::endl;
165 if( word !=
"FftWindowFunction:" ){
166 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read FftWindowFunction header!" << std::endl;
172 if( word !=
"ComputeMagnitude:" ){
173 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read ComputeMagnitude header!" << std::endl;
179 if( word !=
"ComputePhase:" ){
180 errorLog <<
"loadModelFromFile(fstream &file) - Failed to read ComputePhase header!" << std::endl;
186 return init(fftWindowSize,hopSize,numInputDimensions,fftWindowFunction,computeMagnitude,computePhase);
189 bool FFT::init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,
bool computeMagnitude,
bool computePhase,DataType inputType,DataType outputType){
195 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - fftWindowSize is not a power of two!" << std::endl;
199 if( !validateFFTWindowFunction( fftWindowFunction ) ){
200 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - Unkown Window Function!" << std::endl;
210 this->inputType = inputType;
211 this->outputType = outputType;
213 featureDataReady =
false;
214 numInputDimensions = numDimensions;
217 numOutputDimensions = 0;
218 if( computePhase ) numOutputDimensions += fftWindowSize/2 * numInputDimensions;
219 if( computeMagnitude ) numOutputDimensions += fftWindowSize/2 * numInputDimensions;
222 featureVector.
resize( numOutputDimensions, 0);
237 for(
unsigned int i=0; i<numInputDimensions; i++){
238 if( !
fft[i].
init(fftWindowSize,fftWindowFunction,computeMagnitude,computePhase) ){
239 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - Failed to initialize fft!" << std::endl;
251 return update( inputVector );
255 return update( inputMatrix );
261 errorLog <<
"update(const Float x) - Not initialized!" << std::endl;
265 if( numInputDimensions != 1 ){
266 errorLog <<
"update(const Float x) - The size of the input (1) does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
276 errorLog <<
"update(const VectorFloat &x) - Not initialized!" << std::endl;
280 if( x.size() != numInputDimensions ){
281 errorLog <<
"update(const VectorFloat &x) - The size of the input (" << x.size() <<
") does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
288 featureDataReady =
false;
293 for(UINT j=0; j<numInputDimensions; j++){
302 errorLog <<
"update(const VectorFloat &x) - Failed to compute FFT!" << std::endl;
308 featureDataReady =
true;
312 for(UINT j=0; j<numInputDimensions; j++){
314 Float *mag =
fft[j].getMagnitudeDataPtr();
315 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
316 featureVector[index++] = *mag++;
320 Float *phase =
fft[j].getPhaseDataPtr();
321 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
322 featureVector[index++] = *phase++;
334 errorLog <<
"update(const MatrixFloat &x) - Not initialized!" << std::endl;
339 errorLog <<
"update(const MatrixFloat &x) - The number of columns in the inputMatrix (" << x.
getNumCols() <<
") does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
343 featureDataReady =
false;
353 for(UINT j=0; j<numInputDimensions; j++){
362 errorLog <<
"update(const VectorFloat &x) - Failed to compute FFT!" << std::endl;
368 featureDataReady =
true;
372 for(UINT j=0; j<numInputDimensions; j++){
374 Float *mag =
fft[j].getMagnitudeDataPtr();
375 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
376 featureVector[index++] = *mag++;
380 Float *phase =
fft[j].getPhaseDataPtr();
381 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
382 featureVector[index++] = *phase++;
411 if(initialized){
return hopSize; }
422 if( !initialized )
return 0;
436 VectorFloat FFT::getFrequencyBins(
const unsigned int sampleRate){
441 freqBins[i] = (i*sampleRate) / fftWindowSize;
452 errorLog <<
"setHopSize(UINT hopSize) - The hopSize value must be greater than zero!" << std::endl;
462 errorLog <<
"setFFTWindowSize(UINT fftWindowSize) - fftWindowSize must be a power of two!" << std::endl;
468 if( validateFFTWindowFunction( fftWindowFunction ) ){
489 if (x < 2)
return false;
490 if (x & (x - 1))
return false;
494 bool FFT::validateFFTWindowFunction(UINT fftWindowFunction){
495 if( fftWindowFunction != RECTANGULAR_WINDOW && fftWindowFunction != BARTLETT_WINDOW &&
496 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)