STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
arm_rfft_q15.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_rfft_q15.c
9 *
10 * Description: RFFT & RIFFT Q15 process function
11 *
12 *
13 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * - Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * - Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in
22 * the documentation and/or other materials provided with the
23 * distribution.
24 * - Neither the name of ARM LIMITED nor the names of its contributors
25 * may be used to endorse or promote products derived from this
26 * software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 * -------------------------------------------------------------------- */
41 
42 #include "arm_math.h"
43 
44 /*--------------------------------------------------------------------
45 * Internal functions prototypes
46 --------------------------------------------------------------------*/
47 
49  q15_t * pSrc,
50  uint32_t fftLen,
51  q15_t * pATable,
52  q15_t * pBTable,
53  q15_t * pDst,
54  uint32_t modifier);
55 
57  q15_t * pSrc,
58  uint32_t fftLen,
59  q15_t * pATable,
60  q15_t * pBTable,
61  q15_t * pDst,
62  uint32_t modifier);
63 
88  const arm_rfft_instance_q15 * S,
89  q15_t * pSrc,
90  q15_t * pDst)
91 {
92  const arm_cfft_instance_q15 *S_CFFT = S->pCfft;
93  uint32_t i;
94  uint32_t L2 = S->fftLenReal >> 1;
95 
96  /* Calculation of RIFFT of input */
97  if(S->ifftFlagR == 1u)
98  {
99  /* Real IFFT core process */
100  arm_split_rifft_q15(pSrc, L2, S->pTwiddleAReal,
101  S->pTwiddleBReal, pDst, S->twidCoefRModifier);
102 
103  /* Complex IFFT process */
104  arm_cfft_q15(S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR);
105 
106  for(i=0;i<S->fftLenReal;i++)
107  {
108  pDst[i] = pDst[i] << 1;
109  }
110  }
111  else
112  {
113  /* Calculation of RFFT of input */
114 
115  /* Complex FFT process */
116  arm_cfft_q15(S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR);
117 
118  /* Real FFT core process */
119  arm_split_rfft_q15(pSrc, L2, S->pTwiddleAReal,
120  S->pTwiddleBReal, pDst, S->twidCoefRModifier);
121  }
122 }
123 
141  q15_t * pSrc,
142  uint32_t fftLen,
143  q15_t * pATable,
144  q15_t * pBTable,
145  q15_t * pDst,
146  uint32_t modifier)
147 {
148  uint32_t i; /* Loop Counter */
149  q31_t outR, outI; /* Temporary variables for output */
150  q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
151  q15_t *pSrc1, *pSrc2;
152 #ifndef ARM_MATH_CM0_FAMILY
153  q15_t *pD1, *pD2;
154 #endif
155 
156  // pSrc[2u * fftLen] = pSrc[0];
157  // pSrc[(2u * fftLen) + 1u] = pSrc[1];
158 
159  pCoefA = &pATable[modifier * 2u];
160  pCoefB = &pBTable[modifier * 2u];
161 
162  pSrc1 = &pSrc[2];
163  pSrc2 = &pSrc[(2u * fftLen) - 2u];
164 
165 #ifndef ARM_MATH_CM0_FAMILY
166 
167  /* Run the below code for Cortex-M4 and Cortex-M3 */
168  i = 1u;
169  pD1 = pDst + 2;
170  pD2 = pDst + (4u * fftLen) - 2;
171 
172  for(i = fftLen - 1; i > 0; i--)
173  {
174  /*
175  outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
176  + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
177  pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
178  */
179 
180  /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
181  pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
182  pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
183 
184 
185 #ifndef ARM_MATH_BIG_ENDIAN
186 
187  /* pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] */
188  outR = __SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA));
189 
190 #else
191 
192  /* -(pSrc[2 * i + 1] * pATable[2 * i + 1] - pSrc[2 * i] * pATable[2 * i]) */
193  outR = -(__SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA)));
194 
195 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
196 
197  /* pSrc[2 * n - 2 * i] * pBTable[2 * i] +
198  pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
199  outR = __SMLAD(*__SIMD32(pSrc2), *__SIMD32(pCoefB), outR) >> 16u;
200 
201  /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
202  pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
203 
204 #ifndef ARM_MATH_BIG_ENDIAN
205 
206  outI = __SMUSDX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
207 
208 #else
209 
210  outI = __SMUSDX(*__SIMD32(pCoefB), *__SIMD32(pSrc2)--);
211 
212 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
213 
214  /* (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] */
215  outI = __SMLADX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), outI);
216 
217  /* write output */
218  *pD1++ = (q15_t) outR;
219  *pD1++ = outI >> 16u;
220 
221  /* write complex conjugate output */
222  pD2[0] = (q15_t) outR;
223  pD2[1] = -(outI >> 16u);
224  pD2 -= 2;
225 
226  /* update coefficient pointer */
227  pCoefB = pCoefB + (2u * modifier);
228  pCoefA = pCoefA + (2u * modifier);
229  }
230 
231  pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
232  pDst[(2u * fftLen) + 1u] = 0;
233 
234  pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
235  pDst[1] = 0;
236 
237 #else
238 
239  /* Run the below code for Cortex-M0 */
240  i = 1u;
241 
242  while(i < fftLen)
243  {
244  /*
245  outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
246  + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
247  pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
248  */
249 
250  outR = *pSrc1 * *pCoefA;
251  outR = outR - (*(pSrc1 + 1) * *(pCoefA + 1));
252  outR = outR + (*pSrc2 * *pCoefB);
253  outR = (outR + (*(pSrc2 + 1) * *(pCoefB + 1))) >> 16;
254 
255 
256  /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
257  pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
258  pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
259  */
260 
261  outI = *pSrc2 * *(pCoefB + 1);
262  outI = outI - (*(pSrc2 + 1) * *pCoefB);
263  outI = outI + (*(pSrc1 + 1) * *pCoefA);
264  outI = outI + (*pSrc1 * *(pCoefA + 1));
265 
266  /* update input pointers */
267  pSrc1 += 2u;
268  pSrc2 -= 2u;
269 
270  /* write output */
271  pDst[2u * i] = (q15_t) outR;
272  pDst[(2u * i) + 1u] = outI >> 16u;
273 
274  /* write complex conjugate output */
275  pDst[(4u * fftLen) - (2u * i)] = (q15_t) outR;
276  pDst[((4u * fftLen) - (2u * i)) + 1u] = -(outI >> 16u);
277 
278  /* update coefficient pointer */
279  pCoefB = pCoefB + (2u * modifier);
280  pCoefA = pCoefA + (2u * modifier);
281 
282  i++;
283  }
284 
285  pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
286  pDst[(2u * fftLen) + 1u] = 0;
287 
288  pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
289  pDst[1] = 0;
290 
291 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
292 }
293 
294 
307  q15_t * pSrc,
308  uint32_t fftLen,
309  q15_t * pATable,
310  q15_t * pBTable,
311  q15_t * pDst,
312  uint32_t modifier)
313 {
314  uint32_t i; /* Loop Counter */
315  q31_t outR, outI; /* Temporary variables for output */
316  q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
317  q15_t *pSrc1, *pSrc2;
318  q15_t *pDst1 = &pDst[0];
319 
320  pCoefA = &pATable[0];
321  pCoefB = &pBTable[0];
322 
323  pSrc1 = &pSrc[0];
324  pSrc2 = &pSrc[2u * fftLen];
325 
326 #ifndef ARM_MATH_CM0_FAMILY
327 
328  /* Run the below code for Cortex-M4 and Cortex-M3 */
329  i = fftLen;
330 
331  while(i > 0u)
332  {
333  /*
334  outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
335  pIn[2 * n - 2 * i] * pBTable[2 * i] -
336  pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
337 
338  outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
339  pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
340  pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
341  */
342 
343 
344 #ifndef ARM_MATH_BIG_ENDIAN
345 
346  /* pIn[2 * n - 2 * i] * pBTable[2 * i] -
347  pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
348  outR = __SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB));
349 
350 #else
351 
352  /* -(-pIn[2 * n - 2 * i] * pBTable[2 * i] +
353  pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1])) */
354  outR = -(__SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB)));
355 
356 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
357 
358  /* pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
359  pIn[2 * n - 2 * i] * pBTable[2 * i] */
360  outR = __SMLAD(*__SIMD32(pSrc1), *__SIMD32(pCoefA), outR) >> 16u;
361 
362  /*
363  -pIn[2 * n - 2 * i] * pBTable[2 * i + 1] +
364  pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
365  outI = __SMUADX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
366 
367  /* pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] */
368 
369 #ifndef ARM_MATH_BIG_ENDIAN
370 
371  outI = __SMLSDX(*__SIMD32(pCoefA), *__SIMD32(pSrc1)++, -outI);
372 
373 #else
374 
375  outI = __SMLSDX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), -outI);
376 
377 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
378  /* write output */
379 
380 #ifndef ARM_MATH_BIG_ENDIAN
381 
382  *__SIMD32(pDst1)++ = __PKHBT(outR, (outI >> 16u), 16);
383 
384 #else
385 
386  *__SIMD32(pDst1)++ = __PKHBT((outI >> 16u), outR, 16);
387 
388 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
389 
390  /* update coefficient pointer */
391  pCoefB = pCoefB + (2u * modifier);
392  pCoefA = pCoefA + (2u * modifier);
393 
394  i--;
395  }
396 #else
397  /* Run the below code for Cortex-M0 */
398  i = fftLen;
399 
400  while(i > 0u)
401  {
402  /*
403  outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
404  pIn[2 * n - 2 * i] * pBTable[2 * i] -
405  pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
406  */
407 
408  outR = *pSrc2 * *pCoefB;
409  outR = outR - (*(pSrc2 + 1) * *(pCoefB + 1));
410  outR = outR + (*pSrc1 * *pCoefA);
411  outR = (outR + (*(pSrc1 + 1) * *(pCoefA + 1))) >> 16;
412 
413  /*
414  outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
415  pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
416  pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
417  */
418 
419  outI = *(pSrc1 + 1) * *pCoefA;
420  outI = outI - (*pSrc1 * *(pCoefA + 1));
421  outI = outI - (*pSrc2 * *(pCoefB + 1));
422  outI = outI - (*(pSrc2 + 1) * *(pCoefB));
423 
424  /* update input pointers */
425  pSrc1 += 2u;
426  pSrc2 -= 2u;
427 
428  /* write output */
429  *pDst1++ = (q15_t) outR;
430  *pDst1++ = (q15_t) (outI >> 16);
431 
432  /* update coefficient pointer */
433  pCoefB = pCoefB + (2u * modifier);
434  pCoefA = pCoefA + (2u * modifier);
435 
436  i--;
437  }
438 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
439 }
const arm_cfft_instance_q15 * pCfft
Definition: arm_math.h:2166
uint32_t twidCoefRModifier
Definition: arm_math.h:2163
void arm_split_rfft_q15(q15_t *pSrc, uint32_t fftLen, q15_t *pATable, q15_t *pBTable, q15_t *pDst, uint32_t modifier)
Core Real FFT process.
Definition: arm_rfft_q15.c:140
void arm_cfft_q15(const arm_cfft_instance_q15 *S, q15_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag)
Processing function for the Q15 complex FFT.
Definition: arm_cfft_q15.c:89
int16_t q15_t
16-bit fractional data type in 1.15 format.
Definition: arm_math.h:392
void arm_split_rifft_q15(q15_t *pSrc, uint32_t fftLen, q15_t *pATable, q15_t *pBTable, q15_t *pDst, uint32_t modifier)
Core Real IFFT process.
Definition: arm_rfft_q15.c:306
#define __SIMD32(addr)
definition to read/write two 16 bit values.
Definition: arm_math.h:445
void arm_rfft_q15(const arm_rfft_instance_q15 *S, q15_t *pSrc, q15_t *pDst)
Processing function for the Q15 RFFT/RIFFT.
Definition: arm_rfft_q15.c:87
int32_t q31_t
32-bit fractional data type in 1.31 format.
Definition: arm_math.h:397
Instance structure for the Q15 RFFT/RIFFT function.
Definition: arm_math.h:2158
Instance structure for the fixed-point CFFT/CIFFT function.
Definition: arm_math.h:2107