TEST_FIXTURE(CombFilterData, FirCancellation)
    {
        m_pCombFilter->init(CCombFilterIf::kCombFIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);
        
        // full period length
        for (int c = 0; c < m_iNumChannels; c++)
            CSynthesis::generateSine (m_ppfInputData[c], 1.F/m_fDelay, m_fSampleRate, m_iDataLength, .8F, static_cast<float>(c*M_PI_2));
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, -1.F);

        TestProcess();

        for (int c = 0; c < m_iNumChannels; c++)
            for (int i = static_cast<int>(m_fDelay*m_fSampleRate+.5F); i < m_iDataLength; i++)
                CHECK_CLOSE(0.F, m_ppfOutputData[c][i], 1e-3F);

        // half period length
        m_pCombFilter->reset();
        for (int c = 0; c < m_iNumChannels; c++)
            CSynthesis::generateSine (m_ppfInputData[c], .5F/m_fDelay, m_fSampleRate, m_iDataLength, .8F, static_cast<float>(c*M_PI_2));
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, 1.F);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);

        TestProcess();

        for (int c = 0; c < m_iNumChannels; c++)
            for (int i = static_cast<int>(m_fDelay*m_fSampleRate+.5F); i < m_iDataLength; i++)
                CHECK_CLOSE(0.F, m_ppfOutputData[c][i], 1e-3F);
    }
    TEST_FIXTURE(CombFilterData, FilterOutput)
    {
        //m_fDelay = 2/m_fSampleRate;
        int iDelayInSamples = static_cast<int>(m_fDelay*m_fSampleRate + .5F);
        float fAmplitude    = .77F;

        //dirac
        for (int c = 0; c < m_iNumChannels; c++)
            m_ppfInputData[c][c]    = fAmplitude;

        //FIR
        m_pCombFilter->init(CCombFilterIf::kCombFIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);

        TestProcess();

        for (int c = 0; c < m_iNumChannels; c++)
        {
            for (int i= 0; i < m_iDataLength; i++)
            {
                if (i == c)
                    CHECK_CLOSE(fAmplitude, m_ppfOutputData[c][i], 1e-3F);
                else if (i == c+iDelayInSamples)
                    CHECK_CLOSE(fAmplitude*m_fGain, m_ppfOutputData[c][i], 1e-3F);
                else
                    CHECK_CLOSE(0.F, m_ppfOutputData[c][i], 1e-3F);
            }
        }

        m_pCombFilter->reset();

        //IIR
        m_pCombFilter->init(CCombFilterIf::kCombIIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);

        TestProcess();

        for (int c = 0; c < m_iNumChannels; c++)
        {
            for (int i= 0; i < m_iDataLength; i++)
            {
                if (i == c)
                    CHECK_CLOSE(fAmplitude, m_ppfOutputData[c][i], 1e-3F);
                else if (i == c+iDelayInSamples)
                    CHECK_CLOSE(fAmplitude*m_fGain, m_ppfOutputData[c][i], 1e-3F);
                else if (i == c+2*iDelayInSamples)
                    CHECK_CLOSE(fAmplitude*m_fGain*m_fGain, m_ppfOutputData[c][i], 1e-3F);
                else if (i == c+3*iDelayInSamples)
                    CHECK_CLOSE(fAmplitude*m_fGain*m_fGain*m_fGain, m_ppfOutputData[c][i], 1e-3F);
                else if (i == c+4*iDelayInSamples)
                    CHECK_CLOSE(fAmplitude*m_fGain*m_fGain*m_fGain*m_fGain, m_ppfOutputData[c][i], 1e-3F);
                else if (i == c+5*iDelayInSamples)
                    CHECK_CLOSE(fAmplitude*m_fGain*m_fGain*m_fGain*m_fGain*m_fGain, m_ppfOutputData[c][i], 1e-3F);
                else if ((i-c)%(iDelayInSamples) !=0)
                    CHECK_CLOSE(0.F, m_ppfOutputData[c][i], 1e-3F);
            }
        }
    }
    TEST_FIXTURE(CombFilterData, Inplace)
    {
        //Fir
        m_pCombFilter->init(CCombFilterIf::kCombFIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);

        for (int c = 0; c < m_iNumChannels; c++)
            CSynthesis::generateSine (m_ppfInputData[c], 387.F, m_fSampleRate, m_iDataLength, .8F, static_cast<float>(c*M_PI_2));
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);

        TestProcess();
        m_pCombFilter->reset();
        m_pCombFilter->init(CCombFilterIf::kCombFIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);
        TestProcessInplace();

        for (int c = 0; c < m_iNumChannels; c++)
            CHECK_ARRAY_CLOSE(m_ppfInputData[c], m_ppfOutputData[c], m_iDataLength, 1e-3);

        m_pCombFilter->reset();

        // Iir
        m_pCombFilter->init(CCombFilterIf::kCombIIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);
        for (int c = 0; c < m_iNumChannels; c++)
            CSynthesis::generateSine (m_ppfInputData[c], 387.F, m_fSampleRate, m_iDataLength, .8F, static_cast<float>(c*M_PI_2));
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);

        TestProcess();
        m_pCombFilter->reset();
        m_pCombFilter->init(CCombFilterIf::kCombIIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);
        TestProcessInplace();

        for (int c = 0; c < m_iNumChannels; c++)
            CHECK_ARRAY_CLOSE(m_ppfInputData[c], m_ppfOutputData[c], m_iDataLength, 1e-3);
    }
/*
*********************************************************
* START THIS THREAD FOR DATA PROCESSING
*********************************************************
*/
DWORD CDataProcess::Run(void* pParam){

#ifdef SIMULATE
    uID = timeSetEvent(uTimerDuring,10, (LPTIMECALLBACK)TimeProc,0, TIME_PERIODIC); 
#endif

	//CLEAR THE QUEUE
	global.series_fifo.clear();

	//OPERATE THE SYSTEM.
	while(global.cs_dataprocess.IsOn()){
		if(!g_bCycleCtrol)
			TestProcess();
		else
			OperateProcess();
	}
	return 0;
}
    TEST_FIXTURE(CombFilterData, VaryingBlocksize)
    {
        //Fir
        m_pCombFilter->init(CCombFilterIf::kCombFIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);

        for (int c = 0; c < m_iNumChannels; c++)
            CSynthesis::generateSine (m_ppfInputData[c], 387.F, m_fSampleRate, m_iDataLength, .8F, static_cast<float>(c*M_PI_2));
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);

        TestProcess();

        m_pCombFilter->reset();
        m_pCombFilter->init(CCombFilterIf::kCombFIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);
        {
            int iNumFramesRemaining = m_iDataLength;
            while (iNumFramesRemaining > 0)
            {

                int iNumFrames = std::min(static_cast<float>(iNumFramesRemaining), static_cast<float>(rand())/RAND_MAX*17000);

                for (int c = 0; c < m_iNumChannels; c++)
                {
                    m_ppfInputTmp[c]    = &m_ppfInputData[c][m_iDataLength - iNumFramesRemaining];
                }
                m_pCombFilter->process(m_ppfInputTmp, m_ppfInputTmp, iNumFrames);

                iNumFramesRemaining -= iNumFrames;
            }
        }

        for (int c = 0; c < m_iNumChannels; c++)
            CHECK_ARRAY_CLOSE(m_ppfInputData[c], m_ppfOutputData[c], m_iDataLength, 1e-3);

        //Iir
        m_pCombFilter->init(CCombFilterIf::kCombIIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);

        for (int c = 0; c < m_iNumChannels; c++)
            CSynthesis::generateSine (m_ppfInputData[c], 387.F, m_fSampleRate, m_iDataLength, .8F, static_cast<float>(c*M_PI_2));
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);

        TestProcess();

        m_pCombFilter->reset();
        m_pCombFilter->init(CCombFilterIf::kCombIIR, m_fMaxDelayLength, m_fSampleRate, m_iNumChannels);
        m_pCombFilter->setParam(CCombFilterIf::kParamGain, m_fGain);
        m_pCombFilter->setParam(CCombFilterIf::kParamDelay, m_fDelay);
        {
            int iNumFramesRemaining = m_iDataLength;
            while (iNumFramesRemaining > 0)
            {

                int iNumFrames = std::min(static_cast<float>(iNumFramesRemaining), static_cast<float>(rand())/RAND_MAX*17000);

                for (int c = 0; c < m_iNumChannels; c++)
                {
                    m_ppfInputTmp[c]    = &m_ppfInputData[c][m_iDataLength - iNumFramesRemaining];
                }
                m_pCombFilter->process(m_ppfInputTmp, m_ppfInputTmp, iNumFrames);

                iNumFramesRemaining -= iNumFrames;
            }
        }

        for (int c = 0; c < m_iNumChannels; c++)
            CHECK_ARRAY_CLOSE(m_ppfInputData[c], m_ppfOutputData[c], m_iDataLength, 1e-3);
    }