60#include <Eigen/SparseCore>
64#include <unsupported/Eigen/FFT>
79 FilterParameter(QString(
"Tschebyscheff"), QString(
"A tschebyscheff filter"))
104, m_sFilterName(
"Unknown")
105, m_sFilterShortDescription(
"")
121, m_dCenterFreq(dCenterfreq)
122, m_dBandwidth(dBandwidth)
123, m_dParksWidth(dParkswidth)
124, m_iFilterOrder(iOrder)
125, m_iDesignMethod(iDesignMethod)
126, m_iFilterType(iFilterType)
127, m_sFilterName(sFilterName)
128, m_sFilterShortDescription()
131 qWarning() <<
"[FilterKernel::FilterKernel] Less than 9 taps were provided. Setting number of taps to 9.";
143 iFftLength = iDataSize + m_vecCoeff.cols();
145 iFftLength = pow(2, exp);
148 if(m_vecCoeff.cols() != (iFftLength/2+1)) {
149 fftTransformCoeffs(iFftLength);
156 bool bKeepOverhead)
const
159 RowVectorXd vecDataZeroPad = RowVectorXd::Zero(2*m_vecCoeff.cols() + vecData.cols());
160 RowVectorXd vecFilteredTime = RowVectorXd::Zero(2*m_vecCoeff.cols() + vecData.cols());
162 vecDataZeroPad.segment(m_vecCoeff.cols(), vecData.cols()) = vecData;
165 for(
int i = m_vecCoeff.cols(); i < vecFilteredTime.cols(); i++) {
166 vecFilteredTime(i-m_vecCoeff.cols()) = vecDataZeroPad.segment(i-m_vecCoeff.cols(),m_vecCoeff.cols()) * m_vecCoeff.transpose();
171 return vecFilteredTime.segment(m_vecCoeff.cols()/2, vecData.cols());
174 return vecFilteredTime.head(vecData.cols()+m_vecCoeff.cols());
182 #ifdef EIGEN_FFTW_DEFAULT
183 fftw_make_planner_thread_safe();
187 int iFftLength = vecData.cols() + m_vecCoeff.cols();
189 iFftLength = pow(2, exp);
192 if(m_vecFftCoeff.cols() != (iFftLength/2+1)) {
193 fftTransformCoeffs(iFftLength);
197 Eigen::FFT<double> fft;
198 fft.SetFlag(fft.HalfSpectrum);
201 int iOriginalSize = vecData.cols();
202 if (vecData.cols() < iFftLength) {
203 int iResidual = iFftLength - vecData.cols();
204 vecData.conservativeResize(iFftLength);
205 vecData.tail(iResidual).setZero();
209 RowVectorXcd vecFreqData;
210 fft.fwd(vecFreqData, vecData, iFftLength);
213 vecFreqData = m_vecFftCoeff.array() * vecFreqData.array();
216 fft.inv(vecData, vecFreqData);
220 vecData = vecData.segment(m_vecCoeff.cols()/2, iOriginalSize).eval();
222 vecData = vecData.head(iOriginalSize + m_vecCoeff.cols()).eval();
230 return m_sFilterName;
237 m_sFilterName = sFilterName;
258 return m_iFilterOrder;
265 m_iFilterOrder = iOrder;
272 return m_dCenterFreq;
279 m_dCenterFreq = dCenterFreq;
293 m_dBandwidth = dBandwidth;
300 return m_dParksWidth;
307 m_dParksWidth = dParksWidth;
314 return m_dHighpassFreq;
321 m_dHighpassFreq = dHighpassFreq;
328 return m_dLowpassFreq;
335 m_dLowpassFreq = dLowpassFreq;
349 m_vecCoeff = vecCoeff;
356 return m_vecFftCoeff;
363 m_vecFftCoeff = vecFftCoeff;
368bool FilterKernel::fftTransformCoeffs(
int iFftLength)
370 #ifdef EIGEN_FFTW_DEFAULT
371 fftw_make_planner_thread_safe();
374 if(m_vecCoeff.cols() > iFftLength) {
375 std::cout <<
"[FilterKernel::fftTransformCoeffs] The number of filter taps is bigger than the FFT length."<< std::endl;
380 Eigen::FFT<double> fft;
381 fft.SetFlag(fft.HalfSpectrum);
384 RowVectorXd vecInputFft;
385 if (m_vecCoeff.cols() < iFftLength) {
386 vecInputFft.setZero(iFftLength);
387 vecInputFft.block(0,0,1,m_vecCoeff.cols()) = m_vecCoeff;
389 vecInputFft = m_vecCoeff;
393 RowVectorXcd vecFreqData;
394 fft.fwd(vecFreqData, vecInputFft, iFftLength);
395 m_vecFftCoeff = vecFreqData;;
402void FilterKernel::designFilter()
405 int iFftLength = m_iFilterOrder;
407 iFftLength = pow(2, exp);
409 switch(m_iDesignMethod) {
411 ParksMcClellan filter(m_iFilterOrder,
416 m_vecCoeff = filter.FirCoeff;
419 fftTransformCoeffs(iFftLength);
425 CosineFilter filtercos;
427 switch(m_iFilterType) {
429 filtercos = CosineFilter(iFftLength,
430 (m_dCenterFreq)*(m_sFreq/2.),
431 m_dParksWidth*(m_sFreq/2),
432 (m_dCenterFreq)*(m_sFreq/2),
433 m_dParksWidth*(m_sFreq/2),
440 filtercos = CosineFilter(iFftLength,
441 (m_dCenterFreq)*(m_sFreq/2),
442 m_dParksWidth*(m_sFreq/2),
443 (m_dCenterFreq)*(m_sFreq/2),
444 m_dParksWidth*(m_sFreq/2),
451 filtercos = CosineFilter(iFftLength,
452 (m_dCenterFreq + m_dBandwidth/2)*(m_sFreq/2),
453 m_dParksWidth*(m_sFreq/2),
454 (m_dCenterFreq - m_dBandwidth/2)*(m_sFreq/2),
455 m_dParksWidth*(m_sFreq/2),
463 m_vecCoeff.resize(m_iFilterOrder);
465 m_vecCoeff.head(m_iFilterOrder/2) = filtercos.
m_vecCoeff.tail(m_iFilterOrder/2);
466 m_vecCoeff.tail(m_iFilterOrder/2) = filtercos.
m_vecCoeff.head(m_iFilterOrder/2);
469 fftTransformCoeffs(iFftLength);
475 switch(m_iFilterType) {
478 m_dHighpassFreq = m_dCenterFreq*(m_sFreq/2);
482 m_dLowpassFreq = m_dCenterFreq*(m_sFreq/2);
487 m_dLowpassFreq = (m_dCenterFreq + m_dBandwidth/2)*(m_sFreq/2);
488 m_dHighpassFreq = (m_dCenterFreq - m_dBandwidth/2)*(m_sFreq/2);
498 QString description(
m_designMethods.at(m_iDesignMethod).getName() +
" - " + \
499 QString::number(m_dHighpassFreq,
'g',4) +
"Hz to " + QString::number(m_dLowpassFreq,
'g',4) +
"Hz - " \
500 "Ord: " + QString::number(m_iFilterOrder));
508 if(m_iDesignMethod < 0){
518 if(m_iFilterType < 0){
528 if(iDesignMethod < 0){
531 m_iDesignMethod = iDesignMethod;
542 m_iFilterType = iFilterType;
563 QString sDescription)
Declaration of the CosineFilter class.
The FilterKernel class represents a filter object that generates the FIR filter coefficients using Pa...
Numerics class declaration.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Eigen::RowVectorXd m_vecCoeff
Named filter-design parameter descriptor holding a human-readable name and description (e....
double getBandwidth() const
void setSamplingFrequency(double dSFreq)
double getParksWidth() const
double getCenterFrequency() const
void setCenterFrequency(double dCenterFreq)
double getSamplingFrequency() const
QString getShortDescription() const
Eigen::RowVectorXcd getFftCoefficients() const
void applyFftFilter(Eigen::RowVectorXd &vecData, bool bKeepOverhead=false)
void setHighpassFreq(double dHighpassFreq)
void setCoefficients(const Eigen::RowVectorXd &vecCoeff)
static QVector< FilterParameter > m_designMethods
Eigen::RowVectorXd applyConvFilter(const Eigen::RowVectorXd &vecData, bool bKeepOverhead=false) const
void setBandwidth(double dBandwidth)
void prepareFilter(int iDataSize)
void setFilterOrder(int iOrder)
void setFftCoefficients(const Eigen::RowVectorXcd &vecFftCoeff)
void setParksWidth(double dParksWidth)
FilterKernel()
FilterKernel creates a default FilterKernel object.
void setLowpassFreq(double dLowpassFreq)
static QVector< FilterParameter > m_filterTypes
void setName(const QString &sFilterName)
int getFilterOrder() const
Eigen::RowVectorXd getCoefficients() const
double getLowpassFreq() const
void setFilterType(int iFilterType)
double getHighpassFreq() const
FilterParameter getDesignMethod() const
void setDesignMethod(int iDesignMethod)
FilterParameter getFilterType() const
static double log2(const T d)