1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
4 * $Date: 17. January 2013
7 * Project: CMSIS DSP Library
8 * Title: arm_fir_lattice_q31.c
10 * Description: Q31 FIR lattice filter processing function.
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
17 * - Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * - Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in
21 * the documentation and/or other materials provided with the
23 * - Neither the name of ARM LIMITED nor the names of its contributors
24 * may be used to endorse or promote products derived from this
25 * software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 * -------------------------------------------------------------------- */
44 * @ingroup groupFilters
48 * @addtogroup FIR_Lattice
54 * @brief Processing function for the Q31 FIR lattice filter.
55 * @param[in] *S points to an instance of the Q31 FIR lattice structure.
56 * @param[in] *pSrc points to the block of input data.
57 * @param[out] *pDst points to the block of output data
58 * @param[in] blockSize number of samples to process.
62 * <b>Scaling and Overflow Behavior:</b>
63 * In order to avoid overflows the input signal must be scaled down by 2*log2(numStages) bits.
66 #ifndef ARM_MATH_CM0_FAMILY
68 /* Run the below code for Cortex-M4 and Cortex-M3 */
70 void arm_fir_lattice_q31(
71 const arm_fir_lattice_instance_q31 * S,
76 q31_t *pState; /* State pointer */
77 q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
78 q31_t *px; /* temporary state pointer */
79 q31_t *pk; /* temporary coefficient pointer */
80 q31_t fcurr1, fnext1, gcurr1 = 0, gnext1; /* temporary variables for first sample in loop unrolling */
81 q31_t fcurr2, fnext2, gnext2; /* temporary variables for second sample in loop unrolling */
82 uint32_t numStages = S->numStages; /* Length of the filter */
83 uint32_t blkCnt, stageCnt; /* temporary variables for counts */
86 pState = &S->pState[0];
88 blkCnt = blockSize >> 1u;
90 /* First part of the processing with loop unrolling. Compute 2 outputs at a time.
91 a second loop below computes the remaining 1 sample. */
100 /* Initialize coeff pointer */
103 /* Initialize state pointer */
106 /* read g0(n - 1) from state buffer */
109 /* Read the reflection coefficient */
112 /* for sample 1 processing */
113 /* f1(n) = f0(n) + K1 * g0(n-1) */
114 fnext1 = (q31_t) (((q63_t) gcurr1 * k) >> 32);
116 /* g1(n) = f0(n) * K1 + g0(n-1) */
117 gnext1 = (q31_t) (((q63_t) fcurr1 * (k)) >> 32);
118 fnext1 = fcurr1 + (fnext1 << 1u);
119 gnext1 = gcurr1 + (gnext1 << 1u);
121 /* for sample 1 processing */
122 /* f1(n) = f0(n) + K1 * g0(n-1) */
123 fnext2 = (q31_t) (((q63_t) fcurr1 * k) >> 32);
125 /* g1(n) = f0(n) * K1 + g0(n-1) */
126 gnext2 = (q31_t) (((q63_t) fcurr2 * (k)) >> 32);
127 fnext2 = fcurr2 + (fnext2 << 1u);
128 gnext2 = fcurr1 + (gnext2 << 1u);
130 /* save g1(n) in state buffer */
133 /* f1(n) is saved in fcurr1
134 for next stage processing */
138 stageCnt = (numStages - 1u);
144 /* Read the reflection coefficient */
147 /* read g2(n) from state buffer */
150 /* save g1(n) in state buffer */
153 /* Sample processing for K2, K3.... */
154 /* f2(n) = f1(n) + K2 * g1(n-1) */
155 fnext1 = (q31_t) (((q63_t) gcurr1 * k) >> 32);
156 fnext2 = (q31_t) (((q63_t) gnext1 * k) >> 32);
158 fnext1 = fcurr1 + (fnext1 << 1u);
159 fnext2 = fcurr2 + (fnext2 << 1u);
161 /* g2(n) = f1(n) * K2 + g1(n-1) */
162 gnext2 = (q31_t) (((q63_t) fcurr2 * (k)) >> 32);
163 gnext2 = gnext1 + (gnext2 << 1u);
165 /* g2(n) = f1(n) * K2 + g1(n-1) */
166 gnext1 = (q31_t) (((q63_t) fcurr1 * (k)) >> 32);
167 gnext1 = gcurr1 + (gnext1 << 1u);
169 /* f1(n) is saved in fcurr1
170 for next stage processing */
186 /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
187 ** No loop unrolling is used. */
188 blkCnt = blockSize % 0x2u;
195 /* Initialize coeff pointer */
198 /* Initialize state pointer */
201 /* read g0(n - 1) from state buffer */
204 /* Read the reflection coefficient */
207 /* for sample 1 processing */
208 /* f1(n) = f0(n) + K1 * g0(n-1) */
209 fnext1 = (q31_t) (((q63_t) gcurr1 * k) >> 32);
210 fnext1 = fcurr1 + (fnext1 << 1u);
212 /* g1(n) = f0(n) * K1 + g0(n-1) */
213 gnext1 = (q31_t) (((q63_t) fcurr1 * (k)) >> 32);
214 gnext1 = gcurr1 + (gnext1 << 1u);
216 /* save g1(n) in state buffer */
219 /* f1(n) is saved in fcurr1
220 for next stage processing */
223 stageCnt = (numStages - 1u);
228 /* Read the reflection coefficient */
231 /* read g2(n) from state buffer */
234 /* save g1(n) in state buffer */
237 /* Sample processing for K2, K3.... */
238 /* f2(n) = f1(n) + K2 * g1(n-1) */
239 fnext1 = (q31_t) (((q63_t) gcurr1 * k) >> 32);
240 fnext1 = fcurr1 + (fnext1 << 1u);
242 /* g2(n) = f1(n) * K2 + g1(n-1) */
243 gnext1 = (q31_t) (((q63_t) fcurr1 * (k)) >> 32);
244 gnext1 = gcurr1 + (gnext1 << 1u);
246 /* f1(n) is saved in fcurr1
247 for next stage processing */
268 /* Run the below code for Cortex-M0 */
270 void arm_fir_lattice_q31(
271 const arm_fir_lattice_instance_q31 * S,
276 q31_t *pState; /* State pointer */
277 q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
278 q31_t *px; /* temporary state pointer */
279 q31_t *pk; /* temporary coefficient pointer */
280 q31_t fcurr, fnext, gcurr, gnext; /* temporary variables */
281 uint32_t numStages = S->numStages; /* Length of the filter */
282 uint32_t blkCnt, stageCnt; /* temporary variables for counts */
284 pState = &S->pState[0];
293 /* Initialize coeff pointer */
296 /* Initialize state pointer */
299 /* read g0(n-1) from state buffer */
302 /* for sample 1 processing */
303 /* f1(n) = f0(n) + K1 * g0(n-1) */
304 fnext = (q31_t) (((q63_t) gcurr * (*pk)) >> 31) + fcurr;
305 /* g1(n) = f0(n) * K1 + g0(n-1) */
306 gnext = (q31_t) (((q63_t) fcurr * (*pk++)) >> 31) + gcurr;
307 /* save g1(n) in state buffer */
310 /* f1(n) is saved in fcurr1
311 for next stage processing */
314 stageCnt = (numStages - 1u);
319 /* read g2(n) from state buffer */
322 /* save g1(n) in state buffer */
325 /* Sample processing for K2, K3.... */
326 /* f2(n) = f1(n) + K2 * g1(n-1) */
327 fnext = (q31_t) (((q63_t) gcurr * (*pk)) >> 31) + fcurr;
328 /* g2(n) = f1(n) * K2 + g1(n-1) */
329 gnext = (q31_t) (((q63_t) fcurr * (*pk++)) >> 31) + gcurr;
331 /* f1(n) is saved in fcurr1
332 for next stage processing */
348 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
352 * @} end of FIR_Lattice group