QuakeGod
2024-07-27 842bb64195f958b050867c50db66fc0aa413dafb
提交 | 用户 | age
483170 1 /* ----------------------------------------------------------------------   
Q 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_radix2_f32.c   
9 *   
10 * Description:    Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing 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 void arm_radix2_butterfly_f32(
45   float32_t * pSrc,
46   uint32_t fftLen,
47   float32_t * pCoef,
48   uint16_t twidCoefModifier);
49
50 void arm_radix2_butterfly_inverse_f32(
51   float32_t * pSrc,
52   uint32_t fftLen,
53   float32_t * pCoef,
54   uint16_t twidCoefModifier,
55   float32_t onebyfftLen);
56
57 extern void arm_bitreversal_f32(
58     float32_t * pSrc,
59     uint16_t fftSize,
60     uint16_t bitRevFactor,
61     uint16_t * pBitRevTab);
62
63 /**   
64 * @ingroup groupTransforms   
65 */
66
67 /**   
68 * @addtogroup ComplexFFT   
69 * @{   
70 */
71
72 /**   
73 * @details
74 * @brief Radix-2 CFFT/CIFFT.
75 * @deprecated Do not use this function.  It has been superseded by \ref arm_cfft_f32 and will be removed
76 * in the future.
77 * @param[in]      *S    points to an instance of the floating-point Radix-2 CFFT/CIFFT structure.  
78 * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.  
79 * @return none.
80 */
81
82 void arm_cfft_radix2_f32(
83 const arm_cfft_radix2_instance_f32 * S,
84 float32_t * pSrc)
85 {
86
87    if(S->ifftFlag == 1u)
88    {
89       /*  Complex IFFT radix-2  */
90       arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
91       S->twidCoefModifier, S->onebyfftLen);
92    }
93    else
94    {
95       /*  Complex FFT radix-2  */
96       arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
97       S->twidCoefModifier);
98    }
99
100    if(S->bitReverseFlag == 1u)
101    {
102       /*  Bit Reversal */
103       arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
104    }
105
106 }
107
108
109 /**    
110 * @} end of ComplexFFT group    
111 */
112
113
114
115 /* ----------------------------------------------------------------------    
116 ** Internal helper function used by the FFTs    
117 ** ------------------------------------------------------------------- */
118
119 /*    
120 * @brief  Core function for the floating-point CFFT butterfly process.   
121 * @param[in, out] *pSrc            points to the in-place buffer of floating-point data type.   
122 * @param[in]      fftLen           length of the FFT.   
123 * @param[in]      *pCoef           points to the twiddle coefficient buffer.   
124 * @param[in]      twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.   
125 * @return none.   
126 */
127
128 void arm_radix2_butterfly_f32(
129 float32_t * pSrc,
130 uint32_t fftLen,
131 float32_t * pCoef,
132 uint16_t twidCoefModifier)
133 {
134
135    uint32_t i, j, k, l;
136    uint32_t n1, n2, ia;
137    float32_t xt, yt, cosVal, sinVal;
138    float32_t p0, p1, p2, p3;
139    float32_t a0, a1;
140
141 #ifndef ARM_MATH_CM0_FAMILY
142
143    /*  Initializations for the first stage */
144    n2 = fftLen >> 1;
145    ia = 0;
146    i = 0;
147
148    // loop for groups 
149    for (k = n2; k > 0; k--)
150    {
151       cosVal = pCoef[ia * 2];
152       sinVal = pCoef[(ia * 2) + 1];
153
154       /*  Twiddle coefficients index modifier */
155       ia += twidCoefModifier;
156
157       /*  index calculation for the input as, */
158       /*  pSrc[i + 0], pSrc[i + fftLen/1] */
159       l = i + n2;
160
161       /*  Butterfly implementation */
162       a0 = pSrc[2 * i] + pSrc[2 * l];
163       xt = pSrc[2 * i] - pSrc[2 * l];
164
165       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
166       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
167       
168       p0 = xt * cosVal;
169       p1 = yt * sinVal;
170       p2 = yt * cosVal;
171       p3 = xt * sinVal;  
172       
173       pSrc[2 * i]     = a0;   
174       pSrc[2 * i + 1] = a1;       
175       
176       pSrc[2 * l]     = p0 + p1;
177       pSrc[2 * l + 1] = p2 - p3;
178       
179       i++;
180    }                             // groups loop end 
181
182    twidCoefModifier <<= 1u;
183
184    // loop for stage 
185    for (k = n2; k > 2; k = k >> 1)
186    {
187       n1 = n2;
188       n2 = n2 >> 1;
189       ia = 0;
190
191       // loop for groups 
192       j = 0;
193       do
194       {
195          cosVal = pCoef[ia * 2];
196          sinVal = pCoef[(ia * 2) + 1];
197          ia += twidCoefModifier;
198
199          // loop for butterfly 
200          i = j;
201          do
202          {
203             l = i + n2;
204             a0 = pSrc[2 * i] + pSrc[2 * l];
205             xt = pSrc[2 * i] - pSrc[2 * l];
206
207             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
208             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
209             
210             p0 = xt * cosVal;
211             p1 = yt * sinVal;
212             p2 = yt * cosVal;
213             p3 = xt * sinVal;  
214             
215             pSrc[2 * i] = a0;   
216             pSrc[2 * i + 1] = a1;       
217             
218             pSrc[2 * l]     = p0 + p1;
219             pSrc[2 * l + 1] = p2 - p3;
220             
221             i += n1;
222          } while( i < fftLen );                        // butterfly loop end 
223          j++;
224       } while( j < n2);                          // groups loop end 
225       twidCoefModifier <<= 1u;
226    }                             // stages loop end 
227
228    // loop for butterfly 
229    for (i = 0; i < fftLen; i += 2)
230    {
231       a0 = pSrc[2 * i] + pSrc[2 * i + 2];
232       xt = pSrc[2 * i] - pSrc[2 * i + 2];
233
234       yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
235       a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
236       
237       pSrc[2 * i] = a0;   
238       pSrc[2 * i + 1] = a1;
239       pSrc[2 * i + 2] = xt;
240       pSrc[2 * i + 3] = yt;
241    }                             // groups loop end 
242
243 #else
244  
245    n2 = fftLen;
246
247    // loop for stage 
248    for (k = fftLen; k > 1; k = k >> 1)
249    {
250       n1 = n2;
251       n2 = n2 >> 1;
252       ia = 0;
253
254       // loop for groups 
255       j = 0;
256       do
257       {
258          cosVal = pCoef[ia * 2];
259          sinVal = pCoef[(ia * 2) + 1];
260          ia += twidCoefModifier;
261
262          // loop for butterfly 
263          i = j;
264          do
265          {
266             l = i + n2;
267             a0 = pSrc[2 * i] + pSrc[2 * l];
268             xt = pSrc[2 * i] - pSrc[2 * l];
269
270             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
271             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
272             
273             p0 = xt * cosVal;
274             p1 = yt * sinVal;
275             p2 = yt * cosVal;
276             p3 = xt * sinVal;  
277             
278             pSrc[2 * i] = a0;   
279             pSrc[2 * i + 1] = a1;       
280             
281             pSrc[2 * l]     = p0 + p1;
282             pSrc[2 * l + 1] = p2 - p3;
283             
284             i += n1;
285          } while(i < fftLen);
286          j++;
287       } while(j < n2);
288       twidCoefModifier <<= 1u;
289    }
290
291 #endif //    #ifndef ARM_MATH_CM0_FAMILY
292
293 }
294
295
296 void arm_radix2_butterfly_inverse_f32(
297 float32_t * pSrc,
298 uint32_t fftLen,
299 float32_t * pCoef,
300 uint16_t twidCoefModifier,
301 float32_t onebyfftLen)
302 {
303
304    uint32_t i, j, k, l;
305    uint32_t n1, n2, ia;
306    float32_t xt, yt, cosVal, sinVal;
307    float32_t p0, p1, p2, p3;
308    float32_t a0, a1;
309
310 #ifndef ARM_MATH_CM0_FAMILY
311
312    n2 = fftLen >> 1;
313    ia = 0;
314
315    // loop for groups 
316    for (i = 0; i < n2; i++)
317    {
318       cosVal = pCoef[ia * 2];
319       sinVal = pCoef[(ia * 2) + 1];
320       ia += twidCoefModifier;
321
322       l = i + n2;
323       a0 = pSrc[2 * i] + pSrc[2 * l];
324       xt = pSrc[2 * i] - pSrc[2 * l];
325
326       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
327       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
328       
329       p0 = xt * cosVal;
330       p1 = yt * sinVal;
331       p2 = yt * cosVal;
332       p3 = xt * sinVal;  
333       
334       pSrc[2 * i] = a0;   
335       pSrc[2 * i + 1] = a1;       
336       
337       pSrc[2 * l]     = p0 - p1;
338       pSrc[2 * l + 1] = p2 + p3;  
339    }                             // groups loop end 
340
341    twidCoefModifier <<= 1u;
342
343    // loop for stage 
344    for (k = fftLen / 2; k > 2; k = k >> 1)
345    {
346       n1 = n2;
347       n2 = n2 >> 1;
348       ia = 0;
349
350       // loop for groups 
351       j = 0;
352       do
353       {
354          cosVal = pCoef[ia * 2];
355          sinVal = pCoef[(ia * 2) + 1];
356          ia += twidCoefModifier;
357
358          // loop for butterfly 
359          i = j;
360          do
361          {
362             l = i + n2;
363             a0 = pSrc[2 * i] + pSrc[2 * l];
364             xt = pSrc[2 * i] - pSrc[2 * l];
365
366             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
367             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
368             
369             p0 = xt * cosVal;
370             p1 = yt * sinVal;
371             p2 = yt * cosVal;
372             p3 = xt * sinVal;  
373             
374             pSrc[2 * i] = a0;   
375             pSrc[2 * i + 1] = a1;       
376             
377             pSrc[2 * l]     = p0 - p1;
378             pSrc[2 * l + 1] = p2 + p3; 
379
380             i += n1;
381          } while( i < fftLen );                 // butterfly loop end 
382          j++;
383       } while(j < n2);                      // groups loop end 
384
385       twidCoefModifier <<= 1u;
386    }                             // stages loop end 
387
388    // loop for butterfly 
389    for (i = 0; i < fftLen; i += 2)
390    {   
391       a0 = pSrc[2 * i] + pSrc[2 * i + 2];
392       xt = pSrc[2 * i] - pSrc[2 * i + 2];
393       
394       a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
395       yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
396       
397       p0 = a0 * onebyfftLen;
398       p2 = xt * onebyfftLen;
399       p1 = a1 * onebyfftLen;
400       p3 = yt * onebyfftLen; 
401       
402       pSrc[2 * i] = p0;
403       pSrc[2 * i + 1] = p1;  
404       pSrc[2 * i + 2] = p2;       
405       pSrc[2 * i + 3] = p3;
406    }                             // butterfly loop end 
407
408 #else
409
410    n2 = fftLen;
411
412    // loop for stage 
413    for (k = fftLen; k > 2; k = k >> 1)
414    {
415       n1 = n2;
416       n2 = n2 >> 1;
417       ia = 0;
418
419       // loop for groups 
420       j = 0;
421       do
422       {
423          cosVal = pCoef[ia * 2];
424          sinVal = pCoef[(ia * 2) + 1];
425          ia = ia + twidCoefModifier;
426
427          // loop for butterfly 
428          i = j;
429          do
430          {
431             l = i + n2;
432             a0 = pSrc[2 * i] + pSrc[2 * l];
433             xt = pSrc[2 * i] - pSrc[2 * l];
434
435             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
436             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
437             
438             p0 = xt * cosVal;
439             p1 = yt * sinVal;
440             p2 = yt * cosVal;
441             p3 = xt * sinVal;  
442             
443             pSrc[2 * i] = a0;   
444             pSrc[2 * i + 1] = a1;       
445             
446             pSrc[2 * l]     = p0 - p1;
447             pSrc[2 * l + 1] = p2 + p3;  
448             
449             i += n1;
450          } while( i < fftLen );                    // butterfly loop end 
451          j++;
452       } while( j < n2 );                      // groups loop end 
453
454       twidCoefModifier = twidCoefModifier << 1u;
455    }                             // stages loop end 
456
457    n1 = n2;
458    n2 = n2 >> 1;
459
460    // loop for butterfly 
461    for (i = 0; i < fftLen; i += n1)
462    {
463       l = i + n2;
464       
465       a0 = pSrc[2 * i] + pSrc[2 * l];
466       xt = pSrc[2 * i] - pSrc[2 * l];
467       
468       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
469       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
470       
471       p0 = a0 * onebyfftLen;
472       p2 = xt * onebyfftLen;
473       p1 = a1 * onebyfftLen;
474       p3 = yt * onebyfftLen; 
475       
476       pSrc[2 * i] = p0;
477       pSrc[2u * l] = p2;
478      
479       pSrc[2 * i + 1] = p1;    
480       pSrc[2u * l + 1u] = p3;
481    }                             // butterfly loop end 
482
483 #endif //      #ifndef ARM_MATH_CM0_FAMILY
484
485 }