21 #define GRT_DLL_EXPORTS 27 const std::string FIRFilter::id =
"FIRFilter";
36 this->numInputDimensions = numDimensions;
48 this->cutoffFrequencyLower = 0;
49 this->cutoffFrequencyUpper = 0;
54 this->cutoffFrequency = 0;
73 this->filterType = rhs.filterType;
74 this->numTaps = rhs.numTaps;
75 this->sampleRate = rhs.sampleRate;
76 this->cutoffFrequency = rhs.cutoffFrequency;
77 this->cutoffFrequencyLower = rhs.cutoffFrequencyLower;
78 this->cutoffFrequencyUpper = rhs.cutoffFrequencyUpper;
79 this->gain = rhs.gain;
90 if( preProcessing == NULL )
return false;
95 *
this = *
dynamic_cast<const FIRFilter*
>(preProcessing);
100 errorLog <<
"deepCopyFrom(const PreProcessing *preProcessing) - PreProcessing Types Do Not Match!" << std::endl;
108 errorLog <<
"process(const VectorFloat &inputVector) - Not initialized!" << std::endl;
112 if( inputVector.size() != numInputDimensions ){
113 errorLog <<
"process(const VectorFloat &inputVector) - The size of the inputVector (" << inputVector.size() <<
") does not match that of the filter (" << numInputDimensions <<
")!" << std::endl;
121 if( processedData.size() == numOutputDimensions )
return true;
133 for(UINT n=0; n<numInputDimensions; n++){
134 for(UINT i=0; i<numTaps; i++){
156 if( !file.is_open() ){
157 errorLog <<
"saveSettingsToFile(fstream &file) - The file is not open!" << std::endl;
162 file <<
"GRT_FIR_FILTER_FILE_V1.0" << std::endl;
166 errorLog <<
"saveSettingsToFile(fstream &file) - Failed to save base settings to file!" << std::endl;
171 file <<
"FilterType: " << filterType << std::endl;
172 file <<
"NumTaps: " << numTaps << std::endl;
173 file <<
"SampleRate: " << sampleRate << std::endl;
174 file <<
"CutoffFrequency: " << cutoffFrequency << std::endl;
175 file <<
"CutoffFrequencyLower: " << cutoffFrequencyLower << std::endl;
176 file <<
"CutoffFrequencyUpper: " << cutoffFrequencyUpper << std::endl;
177 file <<
"Gain: " << gain << std::endl;
182 file <<
"FilterCoeff: ";
183 for(UINT i=0; i<numTaps; i++){
197 if( !file.is_open() ){
198 errorLog <<
"load(fstream &file) - The file is not open!" << std::endl;
207 if( word !=
"GRT_FIR_FILTER_FILE_V1.0" ){
208 errorLog <<
"load(fstream &file) - Invalid file format!" << std::endl;
214 errorLog <<
"load(fstream &file) - Failed to load preprocessing base settings from file!" << std::endl;
221 if( word !=
"FilterType:" ){
222 errorLog <<
"load(fstream &file) - Failed to read FilterType header!" << std::endl;
227 file >> tmpFilterType;
228 filterType =
static_cast<FilterType>(tmpFilterType);
232 if( word !=
"NumTaps:" ){
233 errorLog <<
"load(fstream &file) - Failed to read NumTaps header!" << std::endl;
241 if( word !=
"SampleRate:" ){
242 errorLog <<
"load(fstream &file) - Failed to read SampleRate header!" << std::endl;
250 if( word !=
"CutoffFrequency:" ){
251 errorLog <<
"load(fstream &file) - Failed to read CutoffFrequency header!" << std::endl;
255 file >> cutoffFrequency;
259 if( word !=
"CutoffFrequencyLower:" ){
260 errorLog <<
"load(fstream &file) - Failed to read CutoffFrequencyLower header!" << std::endl;
264 file >> cutoffFrequencyLower;
268 if( word !=
"CutoffFrequencyUpper:" ){
269 errorLog <<
"load(fstream &file) - Failed to read CutoffFrequencyUpper header!" << std::endl;
273 file >> cutoffFrequencyUpper;
277 if( word !=
"Gain:" ){
278 errorLog <<
"load(fstream &file) - Failed to read Gain header!" << std::endl;
292 if( word !=
"FilterCoeff:" ){
293 errorLog <<
"load(fstream &file) - Failed to read FilterCoeff header!" << std::endl;
298 for(UINT i=0; i<numTaps; i++){
308 if( numInputDimensions == 0 ){
309 errorLog <<
"buildFilter() - Failed to design filter, the number of inputs has not been set!" << std::endl;
317 numOutputDimensions = numInputDimensions;
329 const Float nyquist = sampleRate / 2.0;
331 switch( filterType ){
334 lambda = PI * cutoffFrequency / nyquist;
335 for(UINT i=0; i<numTaps; i++){
336 alpha = i - (numTaps - 1.0) / 2.0;
337 if( alpha == 0.0 ) z[i] = lambda / PI;
338 else z[i] = sin( alpha * lambda ) / (alpha * PI);
343 lambda = PI * cutoffFrequency / nyquist;
344 for(UINT i=0; i<numTaps; i++){
345 alpha = i - (numTaps - 1.0) / 2.0;
346 if( alpha == 0.0 ) z[i] = 1.0 - lambda / PI;
347 else z[i] = -sin( alpha * lambda ) / (alpha * PI);
352 lambda = PI * cutoffFrequencyLower / nyquist;
353 phi = PI * cutoffFrequencyUpper / nyquist;
354 for(UINT i=0; i<numTaps; i++){
355 alpha = i - (numTaps - 1.0) / 2.0;
356 if( alpha == 0.0 ) z[i] = (phi - lambda) / PI;
357 else z[i] = (sin( alpha * phi ) - sin( alpha * lambda )) / (alpha * PI);
361 errorLog <<
"designFilter() - Failed to design filter. Unknown filter type!" << std::endl;
376 errorLog <<
"filter(const Float x) - The filter has not been initialized!" << std::endl;
383 if( result.size() == 0 ){
384 errorLog <<
"filter(const Float x) - Something went wrong, the size of the filtered vector is zero" << std::endl;
395 errorLog <<
"filter(const VectorFloat &x) - Not Initialized!" << std::endl;
399 if( x.size() != numInputDimensions ){
400 errorLog <<
"filter(const VectorFloat &x) - The Number Of Input Dimensions (" << numInputDimensions <<
") does not match the size of the input vector (" << x.size() <<
")!" << std::endl;
407 const UINT K = numTaps-1;
410 for(UINT n=0; n<numInputDimensions; n++){
411 processedData[n] = 0;
412 for(UINT i=0; i<numTaps; i++){
413 processedData[n] += y[K-i][n] * z[i];
415 processedData[n] *= gain;
418 return processedData;
434 return cutoffFrequency;
438 return cutoffFrequencyLower;
442 return cutoffFrequencyUpper;
465 if( filterType ==
LPF || filterType ==
HPF || filterType ==
BPF ){
466 this->filterType = filterType;
471 errorLog <<
"setFilterType(const FilterType filterType) - Failed to set filter type, unknown filter type!" << std::endl;
479 this->numTaps = numTaps;
484 errorLog <<
"setNumTaps(const UINT numTaps) - The number of taps must be greater than zero!" << std::endl;
491 if( sampleRate > 0 ){
492 this->sampleRate = sampleRate;
497 errorLog <<
"setSampleRate(const Float sampleRate) - The sample rate should be a positive number greater than zero!" << std::endl;
504 if( filterType ==
BPF ){
505 warningLog <<
"setCutoffFrequency(const Float cutoffFrequency) - Setting the cutoff frequency has no effect if you are using a BPF. You should set the lower and upper cutoff frequencies instead!" << std::endl;
508 if( cutoffFrequency > 0 ){
509 this->cutoffFrequency = cutoffFrequency;
514 errorLog <<
"setCutoffFrequency(const Float cutoffFrequency) - The cutoffFrequency should be a positive number greater than zero!" << std::endl;
521 if( filterType ==
LPF ){
522 warningLog <<
"setCutoffFrequency(const Float cutoffFrequencyLower,const Float cutoffFrequencyUpper) - Setting the lower and upper cutoff frequency has no effect if you are using a LPF. You should set the cutoff frequency instead!" << std::endl;
525 if( filterType ==
HPF ){
526 warningLog <<
"setCutoffFrequency(const Float cutoffFrequencyLower,const Float cutoffFrequencyUpper) - Setting the lower and upper cutoff frequency has no effect if you are using a HPF. You should set the cutoff frequency instead!" << std::endl;
529 if( cutoffFrequencyLower > 0 && cutoffFrequencyUpper > 0 ){
530 this->cutoffFrequencyLower = cutoffFrequencyLower;
531 this->cutoffFrequencyUpper = cutoffFrequencyUpper;
536 errorLog <<
"setCutoffFrequency(const Float cutoffFrequencyLower,const Float cutoffFrequencyUpper) - The cutoffFrequency should be a positive number greater than zero!" << std::endl;
548 errorLog <<
"setGain(const Float gain) - The gain should be a positive number greater than zero!" << std::endl;
virtual bool clear() override
bool push_back(const T &value)
Vector< VectorFloat > getInputBuffer() const
std::string getId() const
static std::string getId()
bool setNumTaps(const UINT numTaps)
This class implements a Finite Impulse Response (FIR) Filter. It can support a low pass filter...
bool savePreProcessingSettingsToFile(std::fstream &file) const
bool loadPreProcessingSettingsFromFile(std::fstream &file)
Float getCutoffFrequency() const
virtual bool resize(const unsigned int size)
Float filter(const Float x)
Float getCutoffFrequencyUpper() const
virtual bool reset() override
Float getSampleRate() const
bool setCutoffFrequency(const Float cutoffFrequency)
virtual bool process(const VectorFloat &inputVector)
bool setSampleRate(const Float sampleRate)
VectorFloat getFilterCoefficents() const
virtual bool load(std::fstream &file)
virtual bool deepCopyFrom(const PreProcessing *preProcessing)
FIRFilter & operator=(const FIRFilter &rhs)
bool copyBaseVariables(const PreProcessing *preProcessingModule)
FIRFilter(const FilterType filterType=LPF, const UINT numTaps=50, const Float sampleRate=100, const Float cutoffFrequency=10, const Float gain=1, const UINT numDimensions=1)
virtual bool save(std::fstream &file) const
FilterType getFilterType() const
Float getCutoffFrequencyLower() const
Vector< T > getData(const bool rawBuffer=false) const
bool setFilterType(const FilterType filterType)
bool setGain(const Float gain)
bool resize(const unsigned int newBufferSize)