STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
arm_cfft_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_cfft_q31.c
9 *
10 * Description: Combined Radix Decimation in Frequency CFFT fixed point processing function
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 
43 extern void arm_radix4_butterfly_q31(
44  q31_t * pSrc,
45  uint32_t fftLen,
46  q31_t * pCoef,
47  uint32_t twidCoefModifier);
48 
50  q31_t * pSrc,
51  uint32_t fftLen,
52  q31_t * pCoef,
53  uint32_t twidCoefModifier);
54 
55 extern void arm_bitreversal_32(
56  uint32_t * pSrc,
57  const uint16_t bitRevLen,
58  const uint16_t * pBitRevTable);
59 
61  q31_t * pSrc,
62  uint32_t fftLen,
63  const q31_t * pCoef);
64 
66  q31_t * pSrc,
67  uint32_t fftLen,
68  const q31_t * pCoef);
69 
90  const arm_cfft_instance_q31 * S,
91  q31_t * p1,
92  uint8_t ifftFlag,
93  uint8_t bitReverseFlag)
94 {
95  uint32_t L = S->fftLen;
96 
97  if(ifftFlag == 1u)
98  {
99  switch (L)
100  {
101  case 16:
102  case 64:
103  case 256:
104  case 1024:
105  case 4096:
107  break;
108 
109  case 32:
110  case 128:
111  case 512:
112  case 2048:
114  break;
115  }
116  }
117  else
118  {
119  switch (L)
120  {
121  case 16:
122  case 64:
123  case 256:
124  case 1024:
125  case 4096:
126  arm_radix4_butterfly_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 );
127  break;
128 
129  case 32:
130  case 128:
131  case 512:
132  case 2048:
133  arm_cfft_radix4by2_q31 ( p1, L, S->pTwiddle );
134  break;
135  }
136  }
137 
138  if( bitReverseFlag )
139  arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
140 }
141 
147  q31_t * pSrc,
148  uint32_t fftLen,
149  const q31_t * pCoef)
150 {
151  uint32_t i, l;
152  uint32_t n2, ia;
153  q31_t xt, yt, cosVal, sinVal;
154  q31_t p0, p1;
155 
156  n2 = fftLen >> 1;
157  ia = 0;
158  for (i = 0; i < n2; i++)
159  {
160  cosVal = pCoef[2*ia];
161  sinVal = pCoef[2*ia + 1];
162  ia++;
163 
164  l = i + n2;
165  xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2);
166  pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2);
167 
168  yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2);
169  pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2);
170 
171  mult_32x32_keep32_R(p0, xt, cosVal);
172  mult_32x32_keep32_R(p1, yt, cosVal);
173  multAcc_32x32_keep32_R(p0, yt, sinVal);
174  multSub_32x32_keep32_R(p1, xt, sinVal);
175 
176  pSrc[2u * l] = p0 << 1;
177  pSrc[2u * l + 1u] = p1 << 1;
178 
179  }
180 
181  // first col
182  arm_radix4_butterfly_q31( pSrc, n2, (q31_t*)pCoef, 2u);
183  // second col
184  arm_radix4_butterfly_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2u);
185 
186  for (i = 0; i < fftLen >> 1; i++)
187  {
188  p0 = pSrc[4*i+0];
189  p1 = pSrc[4*i+1];
190  xt = pSrc[4*i+2];
191  yt = pSrc[4*i+3];
192 
193  p0 <<= 1;
194  p1 <<= 1;
195  xt <<= 1;
196  yt <<= 1;
197 
198  pSrc[4*i+0] = p0;
199  pSrc[4*i+1] = p1;
200  pSrc[4*i+2] = xt;
201  pSrc[4*i+3] = yt;
202  }
203 
204 }
205 
207  q31_t * pSrc,
208  uint32_t fftLen,
209  const q31_t * pCoef)
210 {
211  uint32_t i, l;
212  uint32_t n2, ia;
213  q31_t xt, yt, cosVal, sinVal;
214  q31_t p0, p1;
215 
216  n2 = fftLen >> 1;
217  ia = 0;
218  for (i = 0; i < n2; i++)
219  {
220  cosVal = pCoef[2*ia];
221  sinVal = pCoef[2*ia + 1];
222  ia++;
223 
224  l = i + n2;
225  xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2);
226  pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2);
227 
228  yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2);
229  pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2);
230 
231  mult_32x32_keep32_R(p0, xt, cosVal);
232  mult_32x32_keep32_R(p1, yt, cosVal);
233  multSub_32x32_keep32_R(p0, yt, sinVal);
234  multAcc_32x32_keep32_R(p1, xt, sinVal);
235 
236  pSrc[2u * l] = p0 << 1;
237  pSrc[2u * l + 1u] = p1 << 1;
238 
239  }
240 
241  // first col
242  arm_radix4_butterfly_inverse_q31( pSrc, n2, (q31_t*)pCoef, 2u);
243  // second col
244  arm_radix4_butterfly_inverse_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2u);
245 
246  for (i = 0; i < fftLen >> 1; i++)
247  {
248  p0 = pSrc[4*i+0];
249  p1 = pSrc[4*i+1];
250  xt = pSrc[4*i+2];
251  yt = pSrc[4*i+3];
252 
253  p0 <<= 1;
254  p1 <<= 1;
255  xt <<= 1;
256  yt <<= 1;
257 
258  pSrc[4*i+0] = p0;
259  pSrc[4*i+1] = p1;
260  pSrc[4*i+2] = xt;
261  pSrc[4*i+3] = yt;
262  }
263 }
264 
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
void arm_radix4_butterfly_q31(q31_t *pSrc, uint32_t fftLen, q31_t *pCoef, uint32_t twidCoefModifier)
Core function for the Q31 CFFT butterfly process.
void arm_cfft_radix4by2_inverse_q31(q31_t *pSrc, uint32_t fftLen, const q31_t *pCoef)
Definition: arm_cfft_q31.c:206
Instance structure for the fixed-point CFFT/CIFFT function.
Definition: arm_math.h:2124
const q31_t * pTwiddle
Definition: arm_math.h:2127
const uint16_t * pBitRevTable
Definition: arm_math.h:2128
#define multAcc_32x32_keep32_R(a, x, y)
Definition: arm_math.h:7042
void arm_bitreversal_32(uint32_t *pSrc, const uint16_t bitRevLen, const uint16_t *pBitRevTable)
#define multSub_32x32_keep32_R(a, x, y)
Definition: arm_math.h:7046
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
void arm_radix4_butterfly_inverse_q31(q31_t *pSrc, uint32_t fftLen, q31_t *pCoef, uint32_t twidCoefModifier)
Core function for the Q31 CIFFT butterfly process.
uint32_t ifftFlag
Definition: FFT.c:112
void arm_cfft_radix4by2_q31(q31_t *pSrc, uint32_t fftLen, const q31_t *pCoef)
Definition: arm_cfft_q31.c:146