1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_fir_f64.c
4 * Description: Floating-point FIR filter processing function
5 *
6 * $Date: 03 June 2022
7 * $Revision: V1.10.1
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 FIR
37 @{
38 */
39
40 /**
41 @brief Processing function for floating-point FIR filter.
42 @param[in] S points to an instance of the floating-point FIR filter structure
43 @param[in] pSrc points to the block of input data
44 @param[out] pDst points to the block of output data
45 @param[in] blockSize number of samples to process
46 */
47 #if defined(ARM_MATH_NEON) && defined(__aarch64__)
arm_fir_f64(const arm_fir_instance_f64 * S,const float64_t * pSrc,float64_t * pDst,uint32_t blockSize)48 ARM_DSP_ATTRIBUTE void arm_fir_f64(
49 const arm_fir_instance_f64 * S,
50 const float64_t * pSrc,
51 float64_t * pDst,
52 uint32_t blockSize)
53 {
54 float64_t *pState = S->pState; /* State pointer */
55 const float64_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
56 float64_t *pStateCurnt; /* Points to the current sample of the state */
57 float64_t *px; /* Temporary pointer for state buffer */
58 const float64_t *pb; /* Temporary pointer for coefficient buffer */
59 float64x2_t pxV;
60 float64x2_t pbV;
61 float64x2_t acc0V;
62 float64_t acc0; /* Accumulator */
63 uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
64 uint32_t i, tapCnt, blkCnt; /* Loop counters */
65
66 /* S->pState points to state array which contains previous frame (numTaps - 1) samples */
67 /* pStateCurnt points to the location where the new input data should be written */
68 pStateCurnt = &(S->pState[(numTaps - 1U)]);
69
70 /* Initialize blkCnt with number of taps */
71 blkCnt = blockSize;
72
73 while (blkCnt > 0U)
74 {
75 /* Copy one sample at a time into state buffer */
76 *pStateCurnt++ = *pSrc++;
77
78 /* Set the accumulator to zero */
79 acc0 = 0.;
80 acc0V = vdupq_n_f64(0.0);
81
82 /* Initialize state pointer */
83 px = pState;
84
85 /* Initialize Coefficient pointer */
86 pb = pCoeffs;
87
88 i = numTaps >> 1U;
89
90 /* Perform the multiply-accumulates */
91 while (i > 0U)
92 {
93 /* acc = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] */
94 pxV = vld1q_f64(px);
95 pbV = vld1q_f64(pb);
96 acc0V = vmlaq_f64(acc0V, pxV, pbV);
97 px+=2;
98 pb+=2;
99
100 i--;
101 }
102
103 acc0 = vaddvq_f64(acc0V);
104 i = numTaps%2 ;
105 while(i >0U)
106 {
107 acc0+= *px++ * *pb++ ;
108 i--;
109 }
110
111 /* Store result in destination buffer. */
112
113 *pDst++ = acc0;
114
115 /* Advance state pointer by 1 for the next sample */
116 pState = pState + 1U;
117
118 /* Decrement loop counter */
119 blkCnt--;
120 }
121
122 /* Processing is complete.
123 Now copy the last numTaps - 1 samples to the start of the state buffer.
124 This prepares the state buffer for the next function call. */
125
126 /* Points to the start of the state buffer */
127 pStateCurnt = S->pState;
128
129 /* Initialize tapCnt with number of taps */
130 tapCnt = (numTaps - 1U);
131
132 /* Copy remaining data */
133 while (tapCnt > 0U)
134 {
135 *pStateCurnt++ = *pState++;
136
137 /* Decrement loop counter */
138 tapCnt--;
139 }
140
141 }
142
143 #else
arm_fir_f64(const arm_fir_instance_f64 * S,const float64_t * pSrc,float64_t * pDst,uint32_t blockSize)144 ARM_DSP_ATTRIBUTE void arm_fir_f64(
145 const arm_fir_instance_f64 * S,
146 const float64_t * pSrc,
147 float64_t * pDst,
148 uint32_t blockSize)
149 {
150 float64_t *pState = S->pState; /* State pointer */
151 const float64_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
152 float64_t *pStateCurnt; /* Points to the current sample of the state */
153 float64_t *px; /* Temporary pointer for state buffer */
154 const float64_t *pb; /* Temporary pointer for coefficient buffer */
155 float64_t acc0; /* Accumulator */
156 uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
157 uint32_t i, tapCnt, blkCnt; /* Loop counters */
158
159 /* S->pState points to state array which contains previous frame (numTaps - 1) samples */
160 /* pStateCurnt points to the location where the new input data should be written */
161 pStateCurnt = &(S->pState[(numTaps - 1U)]);
162
163 /* Initialize blkCnt with number of taps */
164 blkCnt = blockSize;
165
166 while (blkCnt > 0U)
167 {
168 /* Copy one sample at a time into state buffer */
169 *pStateCurnt++ = *pSrc++;
170
171 /* Set the accumulator to zero */
172 acc0 = 0.;
173
174 /* Initialize state pointer */
175 px = pState;
176
177 /* Initialize Coefficient pointer */
178 pb = pCoeffs;
179
180 i = numTaps;
181
182 /* Perform the multiply-accumulates */
183 while (i > 0U)
184 {
185 /* acc = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] */
186 acc0 += *px++ * *pb++;
187
188 i--;
189 }
190
191 /* Store result in destination buffer. */
192 *pDst++ = acc0;
193
194 /* Advance state pointer by 1 for the next sample */
195 pState = pState + 1U;
196
197 /* Decrement loop counter */
198 blkCnt--;
199 }
200
201 /* Processing is complete.
202 Now copy the last numTaps - 1 samples to the start of the state buffer.
203 This prepares the state buffer for the next function call. */
204
205 /* Points to the start of the state buffer */
206 pStateCurnt = S->pState;
207
208 /* Initialize tapCnt with number of taps */
209 tapCnt = (numTaps - 1U);
210
211 /* Copy remaining data */
212 while (tapCnt > 0U)
213 {
214 *pStateCurnt++ = *pState++;
215
216 /* Decrement loop counter */
217 tapCnt--;
218 }
219
220 }
221 #endif
222
223 /**
224 * @} end of FIR group
225 */
226