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); }
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); }