예제 #1
0
        public static unsafe double[] Iir(double[] src, double[] coeff, int initCount)
        {
            int order = coeff.Length / 2 - 1;

            if (src.Length < 5)
            {
                throw new Exception("Invalid IIR src length");
            }

            if (order < 1)
            {
                throw new Exception("Invalid IIR coeff length");
            }

            double[]  dst     = new double[src.Length];
            double[]  delLine = new double[order];
            IppStatus st      = 0;

            //Get buffer size for filter
            int sz = 0;

            st = Ipps.ippsIIRGetStateSize_64f(order, ref sz);
            if (st != IppStatus.ippStsNoErr)
            {
                throw new Exception(string.Format("IIRGetStateSize error {0}", st));
            }

            //Buffer for IIR state information.
            //This is used between calls to ipp and so must be fixed
            byte[] buf = new byte[sz];
            fixed(byte *pbuf = &buf[0])
            {
                IntPtr pstate = IntPtr.Zero;

                st = Ipps.ippsIIRInit_64f(ref pstate, coeff, order, delLine, pbuf);
                if (st != IppStatus.ippStsNoErr)
                {
                    throw new Exception(string.Format("IIRInit error {0}", st));
                }

                //Initialize the filter to minimize settling
                for (int i = 0; i < initCount; ++i)
                {
                    st = Ipps.ippsIIR_64f(src, dst, 1, pstate);
                    if (st != IppStatus.ippStsNoErr)
                    {
                        throw new Exception(string.Format("IIR error {0}", st));
                    }
                }
                //Filter all the data
                st = Ipps.ippsIIR_64f(src, dst, src.Length, pstate);
                if (st != IppStatus.ippStsNoErr)
                {
                    throw new Exception(string.Format("IIR error {0}", st));
                }
            }

            return(dst);
        }
예제 #2
0
        public static unsafe double[] Fir(double[] src, double[] taps, bool shift)
        {
            double[]  dst     = new double[src.Length];
            double[]  delLine = new double[taps.Length];
            IppStatus st      = 0;

            if (src.Length < 5)
            {
                throw new Exception("Invalid FIR src length");
            }

            if (taps.Length < 1)
            {
                throw new Exception("Invalid FIR win length");
            }

            //Initialize delay line from initial sample and sample gradient
            double dd = src[1] - src[0];

            delLine[0] = src[0] - dd;
            for (int i = 1; i < delLine.Length; ++i)
            {
                delLine[i] = delLine[i - 1] - dd;
            }

            //Get buffer size for filter
            int sz = 0;

            st = Ipps.ippsFIRGetStateSize_64f(taps.Length, ref sz);
            if (st != IppStatus.ippStsNoErr)
            {
                throw new Exception(string.Format("FIRGetStateSize error {0}", st));
            }

            //Buffer for FIR state information.
            //This is used between calls to ipp and so must be fixed
            byte[] buf = new byte[sz];
            fixed(byte *pbuf = &buf[0])
            {
                IntPtr pstate = IntPtr.Zero;

                //pstate is initialized to point to somewhere in pbuf

                st = Ipps.ippsFIRInit_64f(ref pstate, taps, taps.Length, delLine, pbuf);
                if (st != IppStatus.ippStsNoErr)
                {
                    throw new Exception(string.Format("FIRInit error {0}", st));
                }

                st = Ipps.ippsFIR_64f(src, dst, src.Length, pstate);
                if (st != IppStatus.ippStsNoErr)
                {
                    throw new Exception(string.Format("FIR error {0}", st));
                }

                if (shift)
                {
                    //Move the samples forward in the dst vector by half the filter length
                    //to compensate for filter phase delay and pad at final sample value and gradient
                    int w2 = taps.Length / 2;
                    Array.Copy(dst, w2, dst, 0, dst.Length - w2);
                    dd = src[src.Length - 1] - src[src.Length - 2];
                    double g = src[src.Length - 1] + dd;
                    double d = 0;
                    for (int i = dst.Length - w2; i < dst.Length; ++i)
                    {
                        st = Ipps.ippsFIROne_64f(g, ref d, pstate);
                        if (st != IppStatus.ippStsNoErr)
                        {
                            throw new Exception(string.Format("FIROne error {0}", st));
                        }
                        dst[i] = d;
                        g     += dd;
                    }
                }
            }

            return(dst);
        }