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
49 @par Size of coefficient arrays:
50 pCoeffs has size 5 * numStages
51
52 pComputedCoeffs has size 8 * numStages
53
54 pComputedCoeffs is the array to be used in arm_biquad_cascade_df2T_init_f32.
55
56 */
arm_biquad_cascade_df2T_compute_coefs_f32(uint8_t numStages,const float32_t * pCoeffs,float32_t * pComputedCoeffs)57 void arm_biquad_cascade_df2T_compute_coefs_f32(
58 uint8_t numStages,
59 const float32_t * pCoeffs,
60 float32_t * pComputedCoeffs)
61 {
62 uint8_t cnt;
63 float32_t b0[4],b1[4],b2[4],a1[4],a2[4];
64
65 cnt = numStages >> 2;
66 while(cnt > 0)
67 {
68 for(int i=0;i<4;i++)
69 {
70 b0[i] = pCoeffs[0];
71 b1[i] = pCoeffs[1];
72 b2[i] = pCoeffs[2];
73 a1[i] = pCoeffs[3];
74 a2[i] = pCoeffs[4];
75 pCoeffs += 5;
76 }
77
78 /* Vec 1 */
79 *pComputedCoeffs++ = 0;
80 *pComputedCoeffs++ = b0[1];
81 *pComputedCoeffs++ = b0[2];
82 *pComputedCoeffs++ = b0[3];
83
84 /* Vec 2 */
85 *pComputedCoeffs++ = 0;
86 *pComputedCoeffs++ = 0;
87 *pComputedCoeffs++ = b0[1] * b0[2];
88 *pComputedCoeffs++ = b0[2] * b0[3];
89
90 /* Vec 3 */
91 *pComputedCoeffs++ = 0;
92 *pComputedCoeffs++ = 0;
93 *pComputedCoeffs++ = 0;
94 *pComputedCoeffs++ = b0[1] * b0[2] * b0[3];
95
96 /* Vec 4 */
97 *pComputedCoeffs++ = b0[0];
98 *pComputedCoeffs++ = b0[0] * b0[1];
99 *pComputedCoeffs++ = b0[0] * b0[1] * b0[2];
100 *pComputedCoeffs++ = b0[0] * b0[1] * b0[2] * b0[3];
101
102 /* Vec 5 */
103 *pComputedCoeffs++ = b1[0];
104 *pComputedCoeffs++ = b1[1];
105 *pComputedCoeffs++ = b1[2];
106 *pComputedCoeffs++ = b1[3];
107
108 /* Vec 6 */
109 *pComputedCoeffs++ = b2[0];
110 *pComputedCoeffs++ = b2[1];
111 *pComputedCoeffs++ = b2[2];
112 *pComputedCoeffs++ = b2[3];
113
114 /* Vec 7 */
115 *pComputedCoeffs++ = a1[0];
116 *pComputedCoeffs++ = a1[1];
117 *pComputedCoeffs++ = a1[2];
118 *pComputedCoeffs++ = a1[3];
119
120 /* Vec 8 */
121 *pComputedCoeffs++ = a2[0];
122 *pComputedCoeffs++ = a2[1];
123 *pComputedCoeffs++ = a2[2];
124 *pComputedCoeffs++ = a2[3];
125
126 cnt--;
127 }
128
129 cnt = numStages & 0x3;
130 while(cnt > 0)
131 {
132 *pComputedCoeffs++ = *pCoeffs++;
133 *pComputedCoeffs++ = *pCoeffs++;
134 *pComputedCoeffs++ = *pCoeffs++;
135 *pComputedCoeffs++ = *pCoeffs++;
136 *pComputedCoeffs++ = *pCoeffs++;
137 cnt--;
138 }
139
140 }
141 #endif
142
143 /**
144 @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
145 @param[in,out] S points to an instance of the filter data structure.
146 @param[in] numStages number of 2nd order stages in the filter.
147 @param[in] pCoeffs points to the filter coefficients.
148 @param[in] pState points to the state buffer.
149
150 @par Coefficient and State Ordering
151 The coefficients are stored in the array <code>pCoeffs</code> in the following order
152 in the not Neon version.
153 <pre>
154 {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
155 </pre>
156
157 @par
158 where <code>b1x</code> and <code>a1x</code> are the coefficients for the first stage,
159 <code>b2x</code> and <code>a2x</code> are the coefficients for the second stage,
160 and so on. The <code>pCoeffs</code> array contains a total of <code>5*numStages</code> values.
161
162 For Neon version, this array is bigger. If numstages = 4x + y, then the array has size:
163 32*x + 5*y
164 and it must be initialized using the function
165 arm_biquad_cascade_df2T_compute_coefs_f32 which is taking the
166 standard array coefficient as parameters.
167
168 But, an array of 8*numstages is a good approximation.
169
170 Then, the initialization can be done with:
171 <pre>
172 arm_biquad_cascade_df2T_compute_coefs_f32(nbCascade,coefs,computedCoefs);
173 arm_biquad_cascade_df2T_init_f32(&SNeon, nbCascade, computedCoefs, stateNeon);
174 </pre>
175
176 @par In this example, computedCoefs is a bigger array of size 8 * numStages.
177 coefs is the standard array:
178
179 <pre>
180 {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
181 </pre>
182
183
184 @par
185 The <code>pState</code> is a pointer to state array.
186 Each Biquad stage has 2 state variables <code>d1,</code> and <code>d2</code>.
187 The 2 state variables for stage 1 are first, then the 2 state variables for stage 2, and so on.
188 The state array has a total length of <code>2*numStages</code> values.
189 The state variables are updated after each block of data is processed; the coefficients are untouched.
190 */
arm_biquad_cascade_df2T_init_f32(arm_biquad_cascade_df2T_instance_f32 * S,uint8_t numStages,const float32_t * pCoeffs,float32_t * pState)191 void arm_biquad_cascade_df2T_init_f32(
192 arm_biquad_cascade_df2T_instance_f32 * S,
193 uint8_t numStages,
194 const float32_t * pCoeffs,
195 float32_t * pState)
196 {
197 /* Assign filter stages */
198 S->numStages = numStages;
199
200 /* Assign coefficient pointer */
201 S->pCoeffs = pCoeffs;
202
203 /* Clear state buffer and size is always 2 * numStages */
204 memset(pState, 0, (2U * (uint32_t) numStages) * sizeof(float32_t));
205
206 /* Assign state pointer */
207 S->pState = pState;
208 }
209
210 /**
211 @} end of BiquadCascadeDF2T group
212 */
213