• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_biquad_cascade_df2T_init_f32.c
4  * Description:  Initialization function for floating-point transposed direct form II Biquad cascade filter
5  *
6  * $Date:        23 April 2021
7  * $Revision:    V1.9.0
8  *
9  * Target Processor: Cortex-M and Cortex-A cores
10  * -------------------------------------------------------------------- */
11 /*
12  * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13  *
14  * SPDX-License-Identifier: Apache-2.0
15  *
16  * Licensed under the Apache License, Version 2.0 (the License); you may
17  * not use this file except in compliance with the License.
18  * You may obtain a copy of the License at
19  *
20  * www.apache.org/licenses/LICENSE-2.0
21  *
22  * Unless required by applicable law or agreed to in writing, software
23  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  * See the License for the specific language governing permissions and
26  * limitations under the License.
27  */
28 
29 #include "dsp/filtering_functions.h"
30 
31 /**
32   @ingroup groupFilters
33  */
34 
35 /**
36   @addtogroup BiquadCascadeDF2T
37   @{
38  */
39 
40 
41 
42 #if defined(ARM_MATH_NEON)
43 /**
44   @brief         Compute new coefficient arrays for use in vectorized filter (Neon only).
45   @param[in]     numStages         number of 2nd order stages in the filter.
46   @param[in]     pCoeffs           points to the original filter coefficients.
47   @param[in]     pComputedCoeffs   points to the new computed coefficients for the vectorized Neon version.
48   @return        none
49 
50   @par   Size of coefficient arrays:
51             pCoeffs has size 5 * numStages
52 
53             pComputedCoeffs has size 8 * numStages
54 
55             pComputedCoeffs is the array to be used in arm_biquad_cascade_df2T_init_f32.
56 
57 */
arm_biquad_cascade_df2T_compute_coefs_f32(uint8_t numStages,const float32_t * pCoeffs,float32_t * pComputedCoeffs)58 void arm_biquad_cascade_df2T_compute_coefs_f32(
59   uint8_t numStages,
60   const float32_t * pCoeffs,
61   float32_t * pComputedCoeffs)
62 {
63    uint8_t cnt;
64    float32_t b0[4],b1[4],b2[4],a1[4],a2[4];
65 
66    cnt = numStages >> 2;
67    while(cnt > 0)
68    {
69       for(int i=0;i<4;i++)
70       {
71         b0[i] = pCoeffs[0];
72         b1[i] = pCoeffs[1];
73         b2[i] = pCoeffs[2];
74         a1[i] = pCoeffs[3];
75         a2[i] = pCoeffs[4];
76         pCoeffs += 5;
77       }
78 
79       /* Vec 1 */
80       *pComputedCoeffs++ = 0;
81       *pComputedCoeffs++ = b0[1];
82       *pComputedCoeffs++ = b0[2];
83       *pComputedCoeffs++ = b0[3];
84 
85       /* Vec 2 */
86       *pComputedCoeffs++ = 0;
87       *pComputedCoeffs++ = 0;
88       *pComputedCoeffs++ = b0[1] * b0[2];
89       *pComputedCoeffs++ = b0[2] * b0[3];
90 
91       /* Vec 3 */
92       *pComputedCoeffs++ = 0;
93       *pComputedCoeffs++ = 0;
94       *pComputedCoeffs++ = 0;
95       *pComputedCoeffs++ = b0[1] * b0[2] * b0[3];
96 
97       /* Vec 4 */
98       *pComputedCoeffs++ = b0[0];
99       *pComputedCoeffs++ = b0[0] * b0[1];
100       *pComputedCoeffs++ = b0[0] * b0[1] * b0[2];
101       *pComputedCoeffs++ = b0[0] * b0[1] * b0[2] * b0[3];
102 
103       /* Vec 5 */
104       *pComputedCoeffs++ = b1[0];
105       *pComputedCoeffs++ = b1[1];
106       *pComputedCoeffs++ = b1[2];
107       *pComputedCoeffs++ = b1[3];
108 
109       /* Vec 6 */
110       *pComputedCoeffs++ = b2[0];
111       *pComputedCoeffs++ = b2[1];
112       *pComputedCoeffs++ = b2[2];
113       *pComputedCoeffs++ = b2[3];
114 
115       /* Vec 7 */
116       *pComputedCoeffs++ = a1[0];
117       *pComputedCoeffs++ = a1[1];
118       *pComputedCoeffs++ = a1[2];
119       *pComputedCoeffs++ = a1[3];
120 
121       /* Vec 8 */
122       *pComputedCoeffs++ = a2[0];
123       *pComputedCoeffs++ = a2[1];
124       *pComputedCoeffs++ = a2[2];
125       *pComputedCoeffs++ = a2[3];
126 
127       cnt--;
128    }
129 
130    cnt = numStages & 0x3;
131    while(cnt > 0)
132    {
133       *pComputedCoeffs++ = *pCoeffs++;
134       *pComputedCoeffs++ = *pCoeffs++;
135       *pComputedCoeffs++ = *pCoeffs++;
136       *pComputedCoeffs++ = *pCoeffs++;
137       *pComputedCoeffs++ = *pCoeffs++;
138       cnt--;
139    }
140 
141 }
142 #endif
143 
144 /**
145   @brief         Initialization function for the floating-point transposed direct form II Biquad cascade filter.
146   @param[in,out] S           points to an instance of the filter data structure.
147   @param[in]     numStages   number of 2nd order stages in the filter.
148   @param[in]     pCoeffs     points to the filter coefficients.
149   @param[in]     pState      points to the state buffer.
150   @return        none
151 
152   @par           Coefficient and State Ordering
153                    The coefficients are stored in the array <code>pCoeffs</code> in the following order
154                    in the not Neon version.
155   <pre>
156       {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
157   </pre>
158 
159   @par
160                    where <code>b1x</code> and <code>a1x</code> are the coefficients for the first stage,
161                    <code>b2x</code> and <code>a2x</code> are the coefficients for the second stage,
162                    and so on.  The <code>pCoeffs</code> array contains a total of <code>5*numStages</code> values.
163 
164                    For Neon version, this array is bigger. If numstages = 4x + y, then the array has size:
165                    32*x + 5*y
166                    and it must be initialized using the function
167                    arm_biquad_cascade_df2T_compute_coefs_f32 which is taking the
168                    standard array coefficient as parameters.
169 
170                    But, an array of 8*numstages is a good approximation.
171 
172                    Then, the initialization can be done with:
173   <pre>
174                    arm_biquad_cascade_df2T_compute_coefs_f32(nbCascade,coefs,computedCoefs);
175                    arm_biquad_cascade_df2T_init_f32(&SNeon, nbCascade, computedCoefs, stateNeon);
176   </pre>
177 
178   @par             In this example, computedCoefs is a bigger array of size 8 * numStages.
179                    coefs is the standard array:
180 
181   <pre>
182       {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
183   </pre>
184 
185 
186   @par
187                    The <code>pState</code> is a pointer to state array.
188                    Each Biquad stage has 2 state variables <code>d1,</code> and <code>d2</code>.
189                    The 2 state variables for stage 1 are first, then the 2 state variables for stage 2, and so on.
190                    The state array has a total length of <code>2*numStages</code> values.
191                    The state variables are updated after each block of data is processed; the coefficients are untouched.
192  */
arm_biquad_cascade_df2T_init_f32(arm_biquad_cascade_df2T_instance_f32 * S,uint8_t numStages,const float32_t * pCoeffs,float32_t * pState)193 void arm_biquad_cascade_df2T_init_f32(
194         arm_biquad_cascade_df2T_instance_f32 * S,
195         uint8_t numStages,
196   const float32_t * pCoeffs,
197         float32_t * pState)
198 {
199   /* Assign filter stages */
200   S->numStages = numStages;
201 
202   /* Assign coefficient pointer */
203   S->pCoeffs = pCoeffs;
204 
205   /* Clear state buffer and size is always 2 * numStages */
206   memset(pState, 0, (2U * (uint32_t) numStages) * sizeof(float32_t));
207 
208   /* Assign state pointer */
209   S->pState = pState;
210 }
211 
212 /**
213   @} end of BiquadCascadeDF2T group
214  */
215