Subversion Repositories LedShow

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 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_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
}