21 #define GRT_DLL_EXPORTS 27 std::string FFT::id =
"FFT";
37 featureDataReady =
false;
38 numInputDimensions = 0;
39 numOutputDimensions = 0;
41 if(
isPowerOfTwo(fftWindowSize) && hopSize > 0 && numDimensions > 0 ){
42 init(fftWindowSize,hopSize,numDimensions,fftWindowFunction,computeMagnitude,computePhase);
83 if( featureExtraction == NULL )
return false;
85 if( this->
getId() == featureExtraction->
getId() ){
88 *
this = *
dynamic_cast<const FFT*
>(featureExtraction);
93 errorLog <<
"deepCopyFrom(FeatureExtraction *featureExtraction) - FeatureExtraction Types Do Not Match!" << std::endl;
100 if( !file.is_open() ){
101 errorLog <<
"save(fstream &file) - The file is not open!" << std::endl;
106 file <<
"GRT_FFT_FILE_V1.0" << std::endl;
110 errorLog <<
"saveFeatureExtractionSettingsToFile(fstream &file) - Failed to save base feature extraction settings to file!" << std::endl;
115 file <<
"HopSize: " <<
hopSize << std::endl;
126 if( !file.is_open() ){
127 errorLog <<
"load(fstream &file) - The file is not open!" << std::endl;
136 if( word !=
"GRT_FFT_FILE_V1.0" ){
137 errorLog <<
"load(fstream &file) - Invalid file format!" << std::endl;
142 errorLog <<
"loadFeatureExtractionSettingsFromFile(fstream &file) - Failed to load base feature extraction settings from file!" << std::endl;
147 if( word !=
"HopSize:" ){
148 errorLog <<
"load(fstream &file) - Failed to read HopSize header!" << std::endl;
154 if( word !=
"FftWindowSize:" ){
155 errorLog <<
"load(fstream &file) - Failed to read FftWindowSize header!" << std::endl;
161 if( word !=
"FftWindowFunction:" ){
162 errorLog <<
"load(fstream &file) - Failed to read FftWindowFunction header!" << std::endl;
168 if( word !=
"ComputeMagnitude:" ){
169 errorLog <<
"load(fstream &file) - Failed to read ComputeMagnitude header!" << std::endl;
175 if( word !=
"ComputePhase:" ){
176 errorLog <<
"load(fstream &file) - Failed to read ComputePhase header!" << std::endl;
182 return init(fftWindowSize,hopSize,numInputDimensions,fftWindowFunction,computeMagnitude,computePhase);
191 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - fftWindowSize is not a power of two!" << std::endl;
195 if( !validateFFTWindowFunction( fftWindowFunction ) ){
196 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - Unkown Window Function!" << std::endl;
206 this->inputType = inputType;
207 this->outputType = outputType;
209 featureDataReady =
false;
210 numInputDimensions = numDimensions;
213 numOutputDimensions = 0;
214 if( computePhase ) numOutputDimensions += fftWindowSize/2 * numInputDimensions;
215 if( computeMagnitude ) numOutputDimensions += fftWindowSize/2 * numInputDimensions;
218 featureVector.
resize( numOutputDimensions, 0);
233 for(
unsigned int i=0; i<numInputDimensions; i++){
234 if( !
fft[i].
init(fftWindowSize,fftWindowFunction,computeMagnitude,computePhase) ){
235 errorLog <<
"init(UINT fftWindowSize,UINT hopSize,UINT numDimensions,UINT fftWindowFunction,bool computeMagnitude,bool computePhase) - Failed to initialize fft!" << std::endl;
247 return update( inputVector );
251 return update( inputMatrix );
257 errorLog <<
"update(const Float x) - Not initialized!" << std::endl;
261 if( numInputDimensions != 1 ){
262 errorLog <<
"update(const Float x) - The size of the input (1) does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
272 errorLog <<
"update(const VectorFloat &x) - Not initialized!" << std::endl;
276 if( x.size() != numInputDimensions ){
277 errorLog <<
"update(const VectorFloat &x) - The size of the input (" << x.size() <<
") does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
284 featureDataReady =
false;
289 for(UINT j=0; j<numInputDimensions; j++){
298 errorLog <<
"update(const VectorFloat &x) - Failed to compute FFT!" << std::endl;
304 featureDataReady =
true;
308 for(UINT j=0; j<numInputDimensions; j++){
310 Float *mag =
fft[j].getMagnitudeDataPtr();
311 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
312 featureVector[index++] = *mag++;
316 Float *phase =
fft[j].getPhaseDataPtr();
317 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
318 featureVector[index++] = *phase++;
330 errorLog <<
"update(const MatrixFloat &x) - Not initialized!" << std::endl;
335 errorLog <<
"update(const MatrixFloat &x) - The number of columns in the inputMatrix (" << x.
getNumCols() <<
") does not match that of the FeatureExtraction (" << numInputDimensions <<
")!" << std::endl;
339 featureDataReady =
false;
349 for(UINT j=0; j<numInputDimensions; j++){
358 errorLog <<
"update(const VectorFloat &x) - Failed to compute FFT!" << std::endl;
364 featureDataReady =
true;
368 for(UINT j=0; j<numInputDimensions; j++){
370 Float *mag =
fft[j].getMagnitudeDataPtr();
371 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
372 featureVector[index++] = *mag++;
376 Float *phase =
fft[j].getPhaseDataPtr();
377 for(UINT i=0; i<
fft[j].getFFTSize()/2; i++){
378 featureVector[index++] = *phase++;
407 if(initialized){
return hopSize; }
418 if( !initialized )
return 0;
432 VectorFloat FFT::getFrequencyBins(
const unsigned int sampleRate)
const {
437 freqBins[i] = (i*sampleRate) / fftWindowSize;
448 errorLog <<
"setHopSize(UINT hopSize) - The hopSize value must be greater than zero!" << std::endl;
458 errorLog <<
"setFFTWindowSize(UINT fftWindowSize) - fftWindowSize must be a power of two!" << std::endl;
464 if( validateFFTWindowFunction( fftWindowFunction ) ){
485 if (x < 2)
return false;
486 if (x & (x - 1))
return false;
491 if( fftWindowFunction != RECTANGULAR_WINDOW && fftWindowFunction != BARTLETT_WINDOW &&
492 fftWindowFunction != HAMMING_WINDOW && fftWindowFunction != HANNING_WINDOW ){
bool push_back(const T &value)
bool setHopSize(const UINT hopSize)
std::string getId() const
UINT dataBufferSize
Stores how much previous input data is stored in the dataBuffer.
UINT getFFTWindowSize() const
bool setFFTWindowFunction(const UINT fftWindowFunction)
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 setFFTWindowSize(const UINT fftWindowSize)
bool computePhase
Tracks if the phase of the FFT needs to be computed.
virtual bool load(std::fstream &file)
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.
virtual bool save(std::fstream &file) const
std::map< unsigned int, unsigned int > windowSizeMap
A map to relate the FFTWindowSize enumerations to actual values.
static std::string getId()
bool setComputeMagnitude(const bool computeMagnitude)
UINT fftWindowSize
Stores the size of the fft (and also the dataBuffer)
unsigned int getNumRows() const
unsigned int getNumCols() const
virtual bool deepCopyFrom(const FeatureExtraction *featureExtraction)
FFT(const UINT fftWindowSize=512, const UINT hopSize=1, const UINT numDimensions=1, const UINT fftWindowFunction=RECTANGULAR_WINDOW, const bool computeMagnitude=true, const bool computePhase=true)
VectorFloat getRow(const unsigned int r) const
UINT getFFTWindowFunction() const
virtual bool computeFeatures(const VectorFloat &inputVector)
bool computeMagnitude
Tracks if the magnitude (and power) of the FFT need to be computed.
bool setComputePhase(const bool computePhase)
FFT & operator=(const FFT &rhs)
UINT getHopCounter() const
bool isPowerOfTwo(UINT x)
A helper function to compute if the input is a power of two.
UINT getDataBufferSize() const
bool update(const Float x)
bool resize(const unsigned int newBufferSize)