• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_cfft_radix2_q31.c
4  * Description:  Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function
5  *
6  * $Date:        23 April 2021
7  * $Revision:    V1.9.0
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/transform_functions.h"
30 
31 void arm_radix2_butterfly_q31(
32         q31_t * pSrc,
33         uint32_t fftLen,
34   const q31_t * pCoef,
35         uint16_t twidCoefModifier);
36 
37 void arm_radix2_butterfly_inverse_q31(
38         q31_t * pSrc,
39         uint32_t fftLen,
40   const q31_t * pCoef,
41         uint16_t twidCoefModifier);
42 
43 void arm_bitreversal_q31(
44         q31_t * pSrc,
45         uint32_t fftLen,
46         uint16_t bitRevFactor,
47   const uint16_t * pBitRevTab);
48 
49 /**
50   @ingroup groupTransforms
51  */
52 
53 /**
54   @addtogroup ComplexFFT
55   @{
56  */
57 
58 /**
59   @brief         Processing function for the fixed-point CFFT/CIFFT.
60   @deprecated    Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed in the future.
61   @param[in]     S    points to an instance of the fixed-point CFFT/CIFFT structure
62   @param[in,out] pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place
63   @return        none
64  */
65 
arm_cfft_radix2_q31(const arm_cfft_radix2_instance_q31 * S,q31_t * pSrc)66 void arm_cfft_radix2_q31(
67   const arm_cfft_radix2_instance_q31 * S,
68         q31_t * pSrc)
69 {
70 
71    if (S->ifftFlag == 1U)
72    {
73       arm_radix2_butterfly_inverse_q31(pSrc, S->fftLen,
74       S->pTwiddle, S->twidCoefModifier);
75    }
76    else
77    {
78       arm_radix2_butterfly_q31(pSrc, S->fftLen,
79       S->pTwiddle, S->twidCoefModifier);
80    }
81 
82    arm_bitreversal_q31(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
83 }
84 
85 /**
86   @} end of ComplexFFT group
87  */
88 
arm_radix2_butterfly_q31(q31_t * pSrc,uint32_t fftLen,const q31_t * pCoef,uint16_t twidCoefModifier)89 void arm_radix2_butterfly_q31(
90         q31_t * pSrc,
91         uint32_t fftLen,
92   const q31_t * pCoef,
93         uint16_t twidCoefModifier)
94 {
95 
96    unsigned i, j, k, l, m;
97    unsigned n1, n2, ia;
98    q31_t xt, yt, cosVal, sinVal;
99    q31_t p0, p1;
100 
101    //N = fftLen;
102    n2 = fftLen;
103 
104    n1 = n2;
105    n2 = n2 >> 1;
106    ia = 0;
107 
108    // loop for groups
109    for (i = 0; i < n2; i++)
110    {
111       cosVal = pCoef[ia * 2];
112       sinVal = pCoef[(ia * 2) + 1];
113       ia = ia + twidCoefModifier;
114 
115       l = i + n2;
116       xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
117       pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
118 
119       yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
120       pSrc[2 * i + 1] =
121         ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
122 
123       mult_32x32_keep32_R(p0, xt, cosVal);
124       mult_32x32_keep32_R(p1, yt, cosVal);
125       multAcc_32x32_keep32_R(p0, yt, sinVal);
126       multSub_32x32_keep32_R(p1, xt, sinVal);
127 
128       pSrc[2U * l] = p0;
129       pSrc[2U * l + 1U] = p1;
130 
131    }                             // groups loop end
132 
133    twidCoefModifier <<= 1U;
134 
135    // loop for stage
136    for (k = fftLen / 2; k > 2; k = k >> 1)
137    {
138       n1 = n2;
139       n2 = n2 >> 1;
140       ia = 0;
141 
142       // loop for groups
143       for (j = 0; j < n2; j++)
144       {
145          cosVal = pCoef[ia * 2];
146          sinVal = pCoef[(ia * 2) + 1];
147          ia = ia + twidCoefModifier;
148 
149          // loop for butterfly
150          i = j;
151          m = fftLen / n1;
152          do
153          {
154             l = i + n2;
155             xt = pSrc[2 * i] - pSrc[2 * l];
156             pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U;
157 
158             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
159             pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U;
160 
161             mult_32x32_keep32_R(p0, xt, cosVal);
162             mult_32x32_keep32_R(p1, yt, cosVal);
163             multAcc_32x32_keep32_R(p0, yt, sinVal);
164             multSub_32x32_keep32_R(p1, xt, sinVal);
165 
166             pSrc[2U * l] = p0;
167             pSrc[2U * l + 1U] = p1;
168             i += n1;
169             m--;
170          } while ( m > 0);                   // butterfly loop end
171 
172       }                           // groups loop end
173 
174       twidCoefModifier <<= 1U;
175    }                             // stages loop end
176 
177    n1 = n2;
178    n2 = n2 >> 1;
179    ia = 0;
180 
181    cosVal = pCoef[ia * 2];
182    sinVal = pCoef[(ia * 2) + 1];
183    ia = ia + twidCoefModifier;
184 
185    // loop for butterfly
186    for (i = 0; i < fftLen; i += n1)
187    {
188       l = i + n2;
189       xt = pSrc[2 * i] - pSrc[2 * l];
190       pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
191 
192       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
193       pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
194 
195       pSrc[2U * l] = xt;
196 
197       pSrc[2U * l + 1U] = yt;
198 
199       i += n1;
200       l = i + n2;
201 
202       xt = pSrc[2 * i] - pSrc[2 * l];
203       pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
204 
205       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
206       pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
207 
208       pSrc[2U * l] = xt;
209 
210       pSrc[2U * l + 1U] = yt;
211 
212    }                             // butterfly loop end
213 
214 }
215 
216 
arm_radix2_butterfly_inverse_q31(q31_t * pSrc,uint32_t fftLen,const q31_t * pCoef,uint16_t twidCoefModifier)217 void arm_radix2_butterfly_inverse_q31(
218         q31_t * pSrc,
219         uint32_t fftLen,
220   const q31_t * pCoef,
221         uint16_t twidCoefModifier)
222 {
223 
224    unsigned i, j, k, l;
225    unsigned n1, n2, ia;
226    q31_t xt, yt, cosVal, sinVal;
227    q31_t p0, p1;
228 
229    //N = fftLen;
230    n2 = fftLen;
231 
232    n1 = n2;
233    n2 = n2 >> 1;
234    ia = 0;
235 
236    // loop for groups
237    for (i = 0; i < n2; i++)
238    {
239       cosVal = pCoef[ia * 2];
240       sinVal = pCoef[(ia * 2) + 1];
241       ia = ia + twidCoefModifier;
242 
243       l = i + n2;
244       xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
245       pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
246 
247       yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
248       pSrc[2 * i + 1] =
249         ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
250 
251       mult_32x32_keep32_R(p0, xt, cosVal);
252       mult_32x32_keep32_R(p1, yt, cosVal);
253       multSub_32x32_keep32_R(p0, yt, sinVal);
254       multAcc_32x32_keep32_R(p1, xt, sinVal);
255 
256       pSrc[2U * l] = p0;
257       pSrc[2U * l + 1U] = p1;
258    }                             // groups loop end
259 
260    twidCoefModifier = twidCoefModifier << 1U;
261 
262    // loop for stage
263    for (k = fftLen / 2; k > 2; k = k >> 1)
264    {
265       n1 = n2;
266       n2 = n2 >> 1;
267       ia = 0;
268 
269       // loop for groups
270       for (j = 0; j < n2; j++)
271       {
272          cosVal = pCoef[ia * 2];
273          sinVal = pCoef[(ia * 2) + 1];
274          ia = ia + twidCoefModifier;
275 
276          // loop for butterfly
277          for (i = j; i < fftLen; i += n1)
278          {
279             l = i + n2;
280             xt = pSrc[2 * i] - pSrc[2 * l];
281             pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U;
282 
283             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
284             pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U;
285 
286             mult_32x32_keep32_R(p0, xt, cosVal);
287             mult_32x32_keep32_R(p1, yt, cosVal);
288             multSub_32x32_keep32_R(p0, yt, sinVal);
289             multAcc_32x32_keep32_R(p1, xt, sinVal);
290 
291             pSrc[2U * l] = p0;
292             pSrc[2U * l + 1U] = p1;
293          }                         // butterfly loop end
294 
295       }                           // groups loop end
296 
297       twidCoefModifier = twidCoefModifier << 1U;
298    }                             // stages loop end
299 
300    n1 = n2;
301    n2 = n2 >> 1;
302    ia = 0;
303 
304    cosVal = pCoef[ia * 2];
305    sinVal = pCoef[(ia * 2) + 1];
306    ia = ia + twidCoefModifier;
307 
308    // loop for butterfly
309    for (i = 0; i < fftLen; i += n1)
310    {
311       l = i + n2;
312       xt = pSrc[2 * i] - pSrc[2 * l];
313       pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
314 
315       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
316       pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
317 
318       pSrc[2U * l] = xt;
319 
320       pSrc[2U * l + 1U] = yt;
321 
322       i += n1;
323       l = i + n2;
324 
325       xt = pSrc[2 * i] - pSrc[2 * l];
326       pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
327 
328       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
329       pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
330 
331       pSrc[2U * l] = xt;
332 
333       pSrc[2U * l + 1U] = yt;
334 
335    }                             // butterfly loop end
336 
337 }
338