Exemplo n.º 1
0
RowVectorXd FilterData::applyFFTFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const
{
    #ifdef EIGEN_FFTW_DEFAULT
        fftw_make_planner_thread_safe();
    #endif

    if(data.cols()<m_dCoeffA.cols() && compensateEdgeEffects==MirrorData) {
        qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols());
        return data;
    }

//    std::cout<<"m_iFFTlength: "<<m_iFFTlength<<std::endl;
//    std::cout<<"2*m_dCoeffA.cols() + data.cols(): "<<2*m_dCoeffA.cols() + data.cols()<<std::endl;

    if(2*m_dCoeffA.cols() + data.cols()>m_iFFTlength) {
        qDebug()<<"Error in FilterData: Number of mirroring/zeropadding size plus data size is bigger then fft length!";
        return data;
    }

    //Do zero padding or mirroring depending on user input
    RowVectorXd t_dataZeroPad = RowVectorXd::Zero(m_iFFTlength);

    switch(compensateEdgeEffects) {
        case MirrorData:
            t_dataZeroPad.head(m_dCoeffA.cols()) = data.head(m_dCoeffA.cols()).reverse();   //front
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;                    //middle
            t_dataZeroPad.tail(m_dCoeffA.cols()) = data.tail(m_dCoeffA.cols()).reverse();   //back
            break;

        case ZeroPad:
            t_dataZeroPad.head(data.cols()) = data;
            break;

        default:
            t_dataZeroPad.head(data.cols()) = data;
            break;
    }

    //generate fft object
    Eigen::FFT<double> fft;
    fft.SetFlag(fft.HalfSpectrum);

    //fft-transform data sequence
    RowVectorXcd t_freqData;
    fft.fwd(t_freqData,t_dataZeroPad);

    //perform frequency-domain filtering
    RowVectorXcd t_filteredFreq = m_dFFTCoeffA.array()*t_freqData.array();

    //inverse-FFT
    RowVectorXd t_filteredTime;
    fft.inv(t_filteredTime,t_filteredFreq);

    //Return filtered data
    if(!keepOverhead)
        return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols());

    return t_filteredTime.head(data.cols()+m_dCoeffA.cols());
}
Exemplo n.º 2
0
RowVectorXd FilterData::applyConvFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const
{
    if(data.cols()<m_dCoeffA.cols() && compensateEdgeEffects==MirrorData){
        qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols());
        return data;
    }

    //Do zero padding or mirroring depending on user input
    RowVectorXd t_dataZeroPad = RowVectorXd::Zero(2*m_dCoeffA.cols() + data.cols());
    RowVectorXd t_filteredTime = RowVectorXd::Zero(2*m_dCoeffA.cols() + data.cols());

    switch(compensateEdgeEffects) {
        case MirrorData:
            t_dataZeroPad.head(m_dCoeffA.cols()) = data.head(m_dCoeffA.cols()).reverse();   //front
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;                    //middle
            t_dataZeroPad.tail(m_dCoeffA.cols()) = data.tail(m_dCoeffA.cols()).reverse();   //back
            break;

        case ZeroPad:
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;
            break;

        default:
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;
            break;
    }

    //Do the convolution
    for(int i=m_dCoeffA.cols(); i<t_filteredTime.cols(); i++)
        t_filteredTime(i-m_dCoeffA.cols()) = t_dataZeroPad.segment(i-m_dCoeffA.cols(),m_dCoeffA.cols()) * m_dCoeffA.transpose();

    //Return filtered data
    if(!keepOverhead)
        return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols());

    return t_filteredTime.head(data.cols()+m_dCoeffA.cols());
}