public MultirateFilter(int upFactor, int downFactor, Complex32[] taps)
        {
            this.upFactor   = upFactor;
            this.downFactor = downFactor;
            //todo: ipp malloc may be required
            this.taps = (Complex32[])taps.Clone();

            int delayCount = (taps.Length + upFactor - 1) / upFactor;

            dlySrc = new Complex32[delayCount];
            dlyDst = new Complex32[delayCount];

            IppStatus rc;
            int       specSize, bufSize;

            rc = Ipp.ippsFIRMRGetStateSize_32fc(taps.Length, upFactor, downFactor,
                                                IppDataType.ipp32fc, &specSize, &bufSize);
            IppException.Check(rc);

            spec = new byte[specSize];
            buf  = new byte[bufSize];

            fixed(Complex32 *pTaps = taps)
            fixed(byte *pSpec = spec)
            {
                rc = Ipp.ippsFIRMRInit_32fc(pTaps, taps.Length, upFactor, 0, downFactor, 0,
                                            (IppsFIRSpec_32fc *)pSpec);
                IppException.Check(rc);
            }
        }
Beispiel #2
0
        //filterCutoff is 0..1 (-6 dB point)

        /// <summary>Initializes a new instance of the <see cref="IppResampler" /> class.</summary>
        /// <param name="inRate">The input sampling rate.</param>
        /// <param name="outRate">The output sampling rate.</param>
        /// <param name="requestedFilterOrder">The requested filter order.</param>
        /// <param name="filterCutoff">The 6-dB cutoff frequency of the anti-aliasing filter
        /// as a fraction of the Nyquist frequency. Must be in the range of 0...1.</param>
        /// <param name="kaiserAlpha">The alpha parameter of the Kaiser filter.</param>
        public IppResampler(int inRate, int outRate, int requestedFilterOrder, float filterCutoff, float kaiserAlpha)
        {
            this.inRate  = inRate;
            this.outRate = outRate;

            //allocate memory for the resampler structure
            int       specSize, filterOrder, filterHeight;
            IppStatus rc;

            rc = Ipp.ippsResamplePolyphaseFixedGetSize_32f(inRate, outRate, requestedFilterOrder, &specSize,
                                                           &filterOrder, &filterHeight, IppHintAlgorithm.ippAlgHintFast);
            IppException.Check(rc);

            //{!} docs suggest to use ippsMalloc_8u(specSize), but that results in memory corruption
            pSpec = (IppsResamplingPolyphaseFixed_32f *)Ipp.ippsMalloc_8u(specSize * filterHeight);

            //initialize IPP resampler
            rc = Ipp.ippsResamplePolyphaseFixedInit_32f(inRate, outRate, filterOrder, filterCutoff,
                                                        kaiserAlpha, pSpec, IppHintAlgorithm.ippAlgHintFast);
            IppException.Check(rc);

            //set up input buffer
            inData     = new float[filterOrder];
            readIndex  = readIndex0 = filterOrder / 2;
            writeIndex = writeIndex0 = filterOrder;
        }
Beispiel #3
0
        /// <summary>Compute the power spectrum from the complex spectrum in the <see cref="FreqData" /> array.</summary>
        /// <param name="power">The buffer for the power spectrum, or <c>null</c>.</param>
        /// <returns>The power spectrum.</returns>
        public float[] PowerSpectrum(float[] power = null)
        {
            int len  = FreqData.Length;
            int half = len / 2;

            if (power == null)
                power = new float[len];

            fixed(Complex32 *p_spectrum = FreqData)
            fixed(float *p_power = power)
            {
                IppStatus rc;

                if ((1 << order) == FreqData.Length)
                {
                    //complex to power, swap the halves
                    rc = sp.ippsPowerSpectr_32fc((Ipp32fc *)p_spectrum, p_power + half, half);
                    IppException.Check(rc);
                    rc = sp.ippsPowerSpectr_32fc((Ipp32fc *)p_spectrum + half, p_power, half);
                    IppException.Check(rc);
                }
                else
                {
                    rc = sp.ippsPowerSpectr_32fc((Ipp32fc *)p_spectrum, p_power, power.Length);
                    IppException.Check(rc);
                }
            }

            return(power);
        }
Beispiel #4
0
        /// <summary>Initializes a new instance of the <see cref="ComplexFft" /> class.</summary>
        /// <param name="size">The size of the FFT transform.</param>
        public ComplexFft(int size) : base(size)
        {
            //allocate input buffer
            TimeData = new Complex32[size];
            FreqData = new Complex32[size];

            //calculate FFT buffer sizes
            int       specBufSize, initBufSize, workBufSize;
            IppStatus rc = sp.ippsFFTGetSize_C_32fc(order, IPP_FFT_NODIV_BY_ANY,
                                                    IppHintAlgorithm.ippAlgHintNone, &specBufSize, &initBufSize, &workBufSize);

            IppException.Check(rc);

            //allocate FFT buffers
            Dispose();
            specBuffer = Ipp.ippsMalloc_8u(specBufSize);
            byte[] initBuf = new byte[initBufSize];
            workBuf = new byte[workBufSize];

            //initialize FFT
            fixed(byte *pInitBuf = initBuf)
            fixed(IppsFFTSpec_C_32fc **ppFftSpec = &pFftSpec)
            {
                rc = sp.ippsFFTInit_C_32fc(ppFftSpec, order, IPP_FFT_NODIV_BY_ANY,
                                           IppHintAlgorithm.ippAlgHintNone, specBuffer, pInitBuf);
            }
            IppException.Check(rc);
        }
Beispiel #5
0
        /// <summary>Computes the inverse FFT transform.</summary>
        public void ComputeInverse()
        {
            fixed(Complex32 *p_timeData = TimeData, p_freqData = FreqData)
            fixed(byte *p_workBuf = workBuf)
            {
                IppStatus rc = sp.ippsFFTInv_CToC_32fc((Ipp32fc *)p_freqData, (Ipp32fc *)p_timeData, pFftSpec, p_workBuf);

                IppException.Check(rc);
            }
        }
Beispiel #6
0
        /// <summary>Computes the forward FFT transform.</summary>
        public void ComputeForward()
        {
            fixed(float *p_timeData = TimeData)
            fixed(Complex32 * p_freqData = FreqData)
            fixed(byte *p_workBuf        = workBuf)
            {
                IppStatus rc = sp.ippsFFTFwd_RToCCS_32f((float *)p_timeData, (float *)p_freqData, pFftSpec, p_workBuf);

                IppException.Check(rc);
            }
        }
Beispiel #7
0
        /// <summary>Converts power ratios to decibels in-place.</summary>
        /// <param name="power">The values to convert.</param>
        public static void PowerToLogPower(float[] power)
        {
            IppStatus rc;
            int       len = power.Length;

            fixed(float *p_power = power)
            {
                rc = sp.ippsAddC_32f(p_power, 1f, p_power, len);
                IppException.Check(rc);
                rc = sp.ippsLn_32f_I(p_power, len);
                IppException.Check(rc);
                rc = sp.ippsMulC_32f_I(LnToDb, p_power, len);
                IppException.Check(rc);
            }
        }
Beispiel #8
0
        /// <summary>Processes the specified input data.</summary>
        /// <param name="inputData">The input data.</param>
        /// <param name="inputOffset">The offset of the first value to process.</param>
        /// <param name="inputStride">The stride in the input data.</param>
        /// <param name="count">The number of values to process.</param>
        /// <returns>The number of resampled values.</returns>
        public int Process(float[] inputData, int inputOffset, int inputStride, int count)
        {
            //resize input buffer, *preserve data*
            int requiredBufferSize = writeIndex + count;

            if (inData.Length < requiredBufferSize)
            {
                Array.Resize(ref inData, requiredBufferSize);
            }

            //de-interleave input data and write to the buffer
            Dsp.StridedToFloat(inputData, inputOffset, inputStride, inData, writeIndex, count);
            writeIndex += count;
            int unusedCount = writeIndex - writeIndex0;

            //estimate output count
            int maxOutCount = (int)(((long)unusedCount * outRate) / inRate) + 2; //+2 is from the example

            if (OutData == null || OutData.Length < maxOutCount)
            {
                OutData = new float[maxOutCount];
            }
            int outCount = 0;

            fixed(float *pSrc = inData, pDst = OutData)
            fixed(double *pTime = &readIndex)
            {
                //resample
                IppStatus rc = Ipp.ippsResamplePolyphaseFixed_32f(pSrc, unusedCount, pDst, 1f, pTime, &outCount, pSpec);

                IppException.Check(rc);
                int usedCount = (int)readIndex - readIndex0;

                //shift unused data back in the buffer
                rc = sp.ippsMove_32f(pSrc + usedCount, pSrc, writeIndex - usedCount);
                IppException.Check(rc);
                readIndex  -= usedCount;
                writeIndex -= usedCount;
            }

            return(outCount);
        }
        public int Process(int inCount)
        {
            int numIters = inCount / downFactor;
            int outCount = numIters * upFactor;

            if (OutData.Length < outCount)
                OutData = new Complex32[outCount];

            fixed(Complex32 *pSrc = InData)
            fixed(Complex32 * pDst    = OutData)
            fixed(byte *pSpec         = spec)
            fixed(Complex32 * pDlySrc = dlySrc)
            fixed(Complex32 * pDlyDst = dlyDst)
            fixed(byte *pBuf          = buf)
            {
                IppStatus rc = Ipp.ippsFIRMR_32fc(pSrc, pDst, numIters,
                                                  (IppsFIRSpec_32fc *)pSpec, pDlySrc, pDlyDst, pBuf);

                IppException.Check(rc);
            }

            return(outCount);
        }
Beispiel #10
0
        /// <summary>Initializes a new instance of the <see cref="RealFft" /> class.</summary>
        /// <param name="size">The size of the FFT transform.</param>
        public RealFft(int size) : base(size)
        {
            TimeData = new float[size];
            FreqData = new Complex32[size / 2 + 1];

            int       specBufSize, initBufSize, workBufSize;
            IppStatus rc = sp.ippsFFTGetSize_R_32f(order, IPP_FFT_NODIV_BY_ANY,
                                                   IppHintAlgorithm.ippAlgHintNone, &specBufSize, &initBufSize, &workBufSize);

            IppException.Check(rc);

            specBuffer = Ipp.ippsMalloc_8u(specBufSize);
            byte[] initBuf = new byte[initBufSize];
            workBuf = new byte[workBufSize];

            fixed(byte *pInitBuf = initBuf)
            fixed(IppsFFTSpec_R_32f **ppFftSpec = &pFftSpec)
            {
                rc = sp.ippsFFTInit_R_32f(ppFftSpec, order, IPP_FFT_NODIV_BY_ANY,
                                          IppHintAlgorithm.ippAlgHintNone, specBuffer, pInitBuf);
            }
            IppException.Check(rc);
        }