STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
arm_fir_decimate_q31.c
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
3 *
4 * $Date: 19. March 2015
5 * $Revision: V.1.4.5
6 *
7 * Project: CMSIS DSP Library
8 * Title: arm_fir_decimate_q31.c
9 *
10 * Description: Q31 FIR Decimator.
11 *
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * - Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * - Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in
21 * the documentation and/or other materials provided with the
22 * distribution.
23 * - Neither the name of ARM LIMITED nor the names of its contributors
24 * may be used to endorse or promote products derived from this
25 * software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 * -------------------------------------------------------------------- */
40 
41 #include "arm_math.h"
42 
74  q31_t * pSrc,
75  q31_t * pDst,
76  uint32_t blockSize)
77 {
78  q31_t *pState = S->pState; /* State pointer */
79  q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
80  q31_t *pStateCurnt; /* Points to the current sample of the state */
81  q31_t x0, c0; /* Temporary variables to hold state and coefficient values */
82  q31_t *px; /* Temporary pointers for state buffer */
83  q31_t *pb; /* Temporary pointers for coefficient buffer */
84  q63_t sum0; /* Accumulator */
85  uint32_t numTaps = S->numTaps; /* Number of taps */
86  uint32_t i, tapCnt, blkCnt, outBlockSize = blockSize / S->M; /* Loop counters */
87 
88 
89 #ifndef ARM_MATH_CM0_FAMILY
90 
91  /* Run the below code for Cortex-M4 and Cortex-M3 */
92 
93  /* S->pState buffer contains previous frame (numTaps - 1) samples */
94  /* pStateCurnt points to the location where the new input data should be written */
95  pStateCurnt = S->pState + (numTaps - 1u);
96 
97  /* Total number of output samples to be computed */
98  blkCnt = outBlockSize;
99 
100  while(blkCnt > 0u)
101  {
102  /* Copy decimation factor number of new input samples into the state buffer */
103  i = S->M;
104 
105  do
106  {
107  *pStateCurnt++ = *pSrc++;
108 
109  } while(--i);
110 
111  /* Set accumulator to zero */
112  sum0 = 0;
113 
114  /* Initialize state pointer */
115  px = pState;
116 
117  /* Initialize coeff pointer */
118  pb = pCoeffs;
119 
120  /* Loop unrolling. Process 4 taps at a time. */
121  tapCnt = numTaps >> 2;
122 
123  /* Loop over the number of taps. Unroll by a factor of 4.
124  ** Repeat until we've computed numTaps-4 coefficients. */
125  while(tapCnt > 0u)
126  {
127  /* Read the b[numTaps-1] coefficient */
128  c0 = *(pb++);
129 
130  /* Read x[n-numTaps-1] sample */
131  x0 = *(px++);
132 
133  /* Perform the multiply-accumulate */
134  sum0 += (q63_t) x0 *c0;
135 
136  /* Read the b[numTaps-2] coefficient */
137  c0 = *(pb++);
138 
139  /* Read x[n-numTaps-2] sample */
140  x0 = *(px++);
141 
142  /* Perform the multiply-accumulate */
143  sum0 += (q63_t) x0 *c0;
144 
145  /* Read the b[numTaps-3] coefficient */
146  c0 = *(pb++);
147 
148  /* Read x[n-numTaps-3] sample */
149  x0 = *(px++);
150 
151  /* Perform the multiply-accumulate */
152  sum0 += (q63_t) x0 *c0;
153 
154  /* Read the b[numTaps-4] coefficient */
155  c0 = *(pb++);
156 
157  /* Read x[n-numTaps-4] sample */
158  x0 = *(px++);
159 
160  /* Perform the multiply-accumulate */
161  sum0 += (q63_t) x0 *c0;
162 
163  /* Decrement the loop counter */
164  tapCnt--;
165  }
166 
167  /* If the filter length is not a multiple of 4, compute the remaining filter taps */
168  tapCnt = numTaps % 0x4u;
169 
170  while(tapCnt > 0u)
171  {
172  /* Read coefficients */
173  c0 = *(pb++);
174 
175  /* Fetch 1 state variable */
176  x0 = *(px++);
177 
178  /* Perform the multiply-accumulate */
179  sum0 += (q63_t) x0 *c0;
180 
181  /* Decrement the loop counter */
182  tapCnt--;
183  }
184 
185  /* Advance the state pointer by the decimation factor
186  * to process the next group of decimation factor number samples */
187  pState = pState + S->M;
188 
189  /* The result is in the accumulator, store in the destination buffer. */
190  *pDst++ = (q31_t) (sum0 >> 31);
191 
192  /* Decrement the loop counter */
193  blkCnt--;
194  }
195 
196  /* Processing is complete.
197  ** Now copy the last numTaps - 1 samples to the satrt of the state buffer.
198  ** This prepares the state buffer for the next function call. */
199 
200  /* Points to the start of the state buffer */
201  pStateCurnt = S->pState;
202 
203  i = (numTaps - 1u) >> 2u;
204 
205  /* copy data */
206  while(i > 0u)
207  {
208  *pStateCurnt++ = *pState++;
209  *pStateCurnt++ = *pState++;
210  *pStateCurnt++ = *pState++;
211  *pStateCurnt++ = *pState++;
212 
213  /* Decrement the loop counter */
214  i--;
215  }
216 
217  i = (numTaps - 1u) % 0x04u;
218 
219  /* copy data */
220  while(i > 0u)
221  {
222  *pStateCurnt++ = *pState++;
223 
224  /* Decrement the loop counter */
225  i--;
226  }
227 
228 #else
229 
230 /* Run the below code for Cortex-M0 */
231 
232  /* S->pState buffer contains previous frame (numTaps - 1) samples */
233  /* pStateCurnt points to the location where the new input data should be written */
234  pStateCurnt = S->pState + (numTaps - 1u);
235 
236  /* Total number of output samples to be computed */
237  blkCnt = outBlockSize;
238 
239  while(blkCnt > 0u)
240  {
241  /* Copy decimation factor number of new input samples into the state buffer */
242  i = S->M;
243 
244  do
245  {
246  *pStateCurnt++ = *pSrc++;
247 
248  } while(--i);
249 
250  /* Set accumulator to zero */
251  sum0 = 0;
252 
253  /* Initialize state pointer */
254  px = pState;
255 
256  /* Initialize coeff pointer */
257  pb = pCoeffs;
258 
259  tapCnt = numTaps;
260 
261  while(tapCnt > 0u)
262  {
263  /* Read coefficients */
264  c0 = *pb++;
265 
266  /* Fetch 1 state variable */
267  x0 = *px++;
268 
269  /* Perform the multiply-accumulate */
270  sum0 += (q63_t) x0 *c0;
271 
272  /* Decrement the loop counter */
273  tapCnt--;
274  }
275 
276  /* Advance the state pointer by the decimation factor
277  * to process the next group of decimation factor number samples */
278  pState = pState + S->M;
279 
280  /* The result is in the accumulator, store in the destination buffer. */
281  *pDst++ = (q31_t) (sum0 >> 31);
282 
283  /* Decrement the loop counter */
284  blkCnt--;
285  }
286 
287  /* Processing is complete.
288  ** Now copy the last numTaps - 1 samples to the start of the state buffer.
289  ** This prepares the state buffer for the next function call. */
290 
291  /* Points to the start of the state buffer */
292  pStateCurnt = S->pState;
293 
294  i = numTaps - 1u;
295 
296  /* copy data */
297  while(i > 0u)
298  {
299  *pStateCurnt++ = *pState++;
300 
301  /* Decrement the loop counter */
302  i--;
303  }
304 
305 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
306 
307 }
308 
int64_t q63_t
64-bit fractional data type in 1.63 format.
Definition: arm_math.h:402
int32_t q31_t
32-bit fractional data type in 1.31 format.
Definition: arm_math.h:397
Instance structure for the Q31 FIR decimator.
Definition: arm_math.h:3280
void arm_fir_decimate_q31(const arm_fir_decimate_instance_q31 *S, q31_t *pSrc, q31_t *pDst, uint32_t blockSize)
Processing function for the Q31 FIR decimator.