/* 
// Copyright 2015 2018 Intel Corporation All Rights Reserved.
// 
// The source code, information and material ("Material") contained herein is
// owned by Intel Corporation or its suppliers or licensors, and title
// to such Material remains with Intel Corporation or its suppliers or
// licensors. The Material contains proprietary information of Intel
// or its suppliers and licensors. The Material is protected by worldwide
// copyright laws and treaty provisions. No part of the Material may be used,
// copied, reproduced, modified, published, uploaded, posted, transmitted,
// distributed or disclosed in any way without Intel's prior express written
// permission. No license under any patent, copyright or other intellectual
// property rights in the Material is granted to or conferred upon you,
// either expressly, by implication, inducement, estoppel or otherwise.
// Any license under such intellectual property rights must be express and
// approved by Intel in writing.
// 
// Unless otherwise agreed by Intel in writing,
// you may not remove or alter this notice or any other notice embedded in
// Materials by Intel or Intel's suppliers or licensors in any way.
*/
#include <stdio.h>
#include "ipps.h"

#define SMP_RATE 1000.f
#define F1 50.f
#define F2 120.f
#define AMPL 10
#define CUT_OFF 0.3
#define LEN 256
#define ORDER 3

int main( ){
    Ipp32f *x, *y, *f1, *f2;
    Ipp32f phase;
    int i, bufferSizeGen, bufferSizeIIRIIR;
    Ipp64f *pTaps;
    Ipp8u *pBufIIRIIR;
    IppsIIRState64f_32f *pStateIIRIIR;
    IppStatus st;

    /* generate test input signal - sum of 2 sinusoids with 50 & 120 Hz */
    f1 = ippsMalloc_32f( LEN );
    f2 = ippsMalloc_32f( LEN );
    x  = ippsMalloc_32f( LEN );
    phase = 3 * (Ipp32f)IPP_PI2; /* ippsTone generates cos, we want sin */
    st = ippsTone_32f( f1, LEN, AMPL, F1/SMP_RATE, &phase, ippAlgHintAccurate ); /* generate 50 Hz sin */
    phase = 3 * (Ipp32f)IPP_PI2; /* restore phase*/
    st |= ippsTone_32f( f2, LEN, AMPL, F2/SMP_RATE, &phase, ippAlgHintAccurate ); /* generate 120 Hz sin */
    st |= ippsAdd_32f( f1, f2, x, LEN ); /* add 50 & 120 Hz sin to form input signal */
    st |= ippsAbs_32f_I( x, LEN ); /* make positive, x contains input signal to be filtered with IIRIIR */
    ippsFree( f1 );
    ippsFree( f2 );
    /* get size of mem buffers for IIR and IIRGen functions */
    st |= ippsIIRIIRGetStateSize64f_32f( ORDER, &bufferSizeIIRIIR );
    st |= ippsIIRGenGetBufferSize      ( ORDER, &bufferSizeGen    );
    /* we can allocate MAX size from two - operations are sequential and therefore buffer can be reused */
    pBufIIRIIR = ippsMalloc_8u( IPP_MAX( bufferSizeGen, bufferSizeIIRIIR ));
    pTaps = ippsMalloc_64f( 2 * ( ORDER + 1 ));
    /* gen LowPass filter coefficients */
    st |= ippsIIRGenLowpass_64f( CUT_OFF/2, 0.0, ORDER, pTaps, ippButterworth, pBufIIRIIR );
    /* init state structure for IIRIIR */
    st |= ippsIIRIIRInit64f_32f( &pStateIIRIIR, pTaps, ORDER, NULL, pBufIIRIIR );
    y = ippsMalloc_32f( LEN ); /* output vector */
    st |=ippsIIRIIR64f_32f( x, y, LEN, pStateIIRIIR );
    printf("idx,\tinput,\toutput\n");
    for( i = 0; i < LEN; i++ ){
        printf("%d,\t%f,\t%f\n", i, x[i], y[i] );
    }
    if( ippStsNoErr != st )
        printf("\nCertain problems in Intel(R) Integrated Primitives (Intel(R) IPP) !\n");
    ippsFree( y );
    ippsFree( pTaps );
    ippsFree( pBufIIRIIR );
    ippsFree( x );
    return 0;
}