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