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