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