/ Drivers / CMSIS / DSP / Source / TransformFunctions / arm_cfft_radix2_q31.c
arm_cfft_radix2_q31.c
  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  
 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  
 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  
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  }