STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
arm_rfft_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_rfft_q31.c
9 *
10 * Description: RFFT & RIFFT Q31 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  q31_t * pSrc,
50  uint32_t fftLen,
51  q31_t * pATable,
52  q31_t * pBTable,
53  q31_t * pDst,
54  uint32_t modifier);
55 
57  q31_t * pSrc,
58  uint32_t fftLen,
59  q31_t * pATable,
60  q31_t * pBTable,
61  q31_t * pDst,
62  uint32_t modifier);
63 
88  const arm_rfft_instance_q31 * S,
89  q31_t * pSrc,
90  q31_t * pDst)
91 {
92  const arm_cfft_instance_q31 *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_q31(pSrc, L2, S->pTwiddleAReal,
101  S->pTwiddleBReal, pDst, S->twidCoefRModifier);
102 
103  /* Complex IFFT process */
104  arm_cfft_q31(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_q31(S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR);
117 
118  /* Real FFT core process */
119  arm_split_rfft_q31(pSrc, L2, S->pTwiddleAReal,
120  S->pTwiddleBReal, pDst, S->twidCoefRModifier);
121  }
122 }
123 
139  q31_t * pSrc,
140  uint32_t fftLen,
141  q31_t * pATable,
142  q31_t * pBTable,
143  q31_t * pDst,
144  uint32_t modifier)
145 {
146  uint32_t i; /* Loop Counter */
147  q31_t outR, outI; /* Temporary variables for output */
148  q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
149  q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
150  q31_t *pOut1 = &pDst[2], *pOut2 = &pDst[(4u * fftLen) - 1u];
151  q31_t *pIn1 = &pSrc[2], *pIn2 = &pSrc[(2u * fftLen) - 1u];
152 
153  /* Init coefficient pointers */
154  pCoefA = &pATable[modifier * 2u];
155  pCoefB = &pBTable[modifier * 2u];
156 
157  i = fftLen - 1u;
158 
159  while(i > 0u)
160  {
161  /*
162  outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
163  + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
164  pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
165  */
166 
167  /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
168  pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
169  pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
170 
171  CoefA1 = *pCoefA++;
172  CoefA2 = *pCoefA;
173 
174  /* outR = (pSrc[2 * i] * pATable[2 * i] */
175  mult_32x32_keep32_R(outR, *pIn1, CoefA1);
176 
177  /* outI = pIn[2 * i] * pATable[2 * i + 1] */
178  mult_32x32_keep32_R(outI, *pIn1++, CoefA2);
179 
180  /* - pSrc[2 * i + 1] * pATable[2 * i + 1] */
181  multSub_32x32_keep32_R(outR, *pIn1, CoefA2);
182 
183  /* (pIn[2 * i + 1] * pATable[2 * i] */
184  multAcc_32x32_keep32_R(outI, *pIn1++, CoefA1);
185 
186  /* pSrc[2 * n - 2 * i] * pBTable[2 * i] */
187  multSub_32x32_keep32_R(outR, *pIn2, CoefA2);
188  CoefB1 = *pCoefB;
189 
190  /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */
191  multSub_32x32_keep32_R(outI, *pIn2--, CoefB1);
192 
193  /* pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */
194  multAcc_32x32_keep32_R(outR, *pIn2, CoefB1);
195 
196  /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
197  multSub_32x32_keep32_R(outI, *pIn2--, CoefA2);
198 
199  /* write output */
200  *pOut1++ = outR;
201  *pOut1++ = outI;
202 
203  /* write complex conjugate output */
204  *pOut2-- = -outI;
205  *pOut2-- = outR;
206 
207  /* update coefficient pointer */
208  pCoefB = pCoefB + (modifier * 2u);
209  pCoefA = pCoefA + ((modifier * 2u) - 1u);
210 
211  i--;
212  }
213  pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
214  pDst[(2u * fftLen) + 1u] = 0;
215 
216  pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
217  pDst[1] = 0;
218 }
219 
231  q31_t * pSrc,
232  uint32_t fftLen,
233  q31_t * pATable,
234  q31_t * pBTable,
235  q31_t * pDst,
236  uint32_t modifier)
237 {
238  q31_t outR, outI; /* Temporary variables for output */
239  q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
240  q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
241  q31_t *pIn1 = &pSrc[0], *pIn2 = &pSrc[(2u * fftLen) + 1u];
242 
243  pCoefA = &pATable[0];
244  pCoefB = &pBTable[0];
245 
246  while(fftLen > 0u)
247  {
248  /*
249  outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
250  pIn[2 * n - 2 * i] * pBTable[2 * i] -
251  pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
252 
253  outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
254  pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
255  pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
256  */
257  CoefA1 = *pCoefA++;
258  CoefA2 = *pCoefA;
259 
260  /* outR = (pIn[2 * i] * pATable[2 * i] */
261  mult_32x32_keep32_R(outR, *pIn1, CoefA1);
262 
263  /* - pIn[2 * i] * pATable[2 * i + 1] */
264  mult_32x32_keep32_R(outI, *pIn1++, -CoefA2);
265 
266  /* pIn[2 * i + 1] * pATable[2 * i + 1] */
267  multAcc_32x32_keep32_R(outR, *pIn1, CoefA2);
268 
269  /* pIn[2 * i + 1] * pATable[2 * i] */
270  multAcc_32x32_keep32_R(outI, *pIn1++, CoefA1);
271 
272  /* pIn[2 * n - 2 * i] * pBTable[2 * i] */
273  multAcc_32x32_keep32_R(outR, *pIn2, CoefA2);
274  CoefB1 = *pCoefB;
275 
276  /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */
277  multSub_32x32_keep32_R(outI, *pIn2--, CoefB1);
278 
279  /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */
280  multAcc_32x32_keep32_R(outR, *pIn2, CoefB1);
281 
282  /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
283  multAcc_32x32_keep32_R(outI, *pIn2--, CoefA2);
284 
285  /* write output */
286  *pDst++ = outR;
287  *pDst++ = outI;
288 
289  /* update coefficient pointer */
290  pCoefB = pCoefB + (modifier * 2u);
291  pCoefA = pCoefA + ((modifier * 2u) - 1u);
292 
293  /* Decrement loop count */
294  fftLen--;
295  }
296 }
void arm_rfft_q31(const arm_rfft_instance_q31 *S, q31_t *pSrc, q31_t *pDst)
Processing function for the Q31 RFFT/RIFFT.
Definition: arm_rfft_q31.c:87
void arm_split_rifft_q31(q31_t *pSrc, uint32_t fftLen, q31_t *pATable, q31_t *pBTable, q31_t *pDst, uint32_t modifier)
Core Real IFFT process.
Definition: arm_rfft_q31.c:230
void arm_cfft_q31(const arm_cfft_instance_q31 *S, q31_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag)
Processing function for the fixed-point complex FFT in Q31 format.
Definition: arm_cfft_q31.c:89
Instance structure for the fixed-point CFFT/CIFFT function.
Definition: arm_math.h:2124
#define multAcc_32x32_keep32_R(a, x, y)
Definition: arm_math.h:7042
#define multSub_32x32_keep32_R(a, x, y)
Definition: arm_math.h:7046
const arm_cfft_instance_q31 * pCfft
Definition: arm_math.h:2191
int32_t q31_t
32-bit fractional data type in 1.31 format.
Definition: arm_math.h:397
#define mult_32x32_keep32_R(a, x, y)
Definition: arm_math.h:7050
Instance structure for the Q31 RFFT/RIFFT function.
Definition: arm_math.h:2183
void arm_split_rfft_q31(q31_t *pSrc, uint32_t fftLen, q31_t *pATable, q31_t *pBTable, q31_t *pDst, uint32_t modifier)
Core Real FFT process.
Definition: arm_rfft_q31.c:138
uint32_t twidCoefRModifier
Definition: arm_math.h:2188