Subversion Repositories DashDisplay

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_rfft_f32.c    
9
*    
10
* Description:  RFFT & RIFFT Floating point process 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_f32(
44
    float32_t * pSrc,
45
    uint16_t fftLen,
46
    float32_t * pCoef,
47
    uint16_t twidCoefModifier);
48
 
49
extern void arm_radix4_butterfly_inverse_f32(
50
    float32_t * pSrc,
51
    uint16_t fftLen,
52
    float32_t * pCoef,
53
    uint16_t twidCoefModifier,
54
    float32_t onebyfftLen);
55
 
56
extern void arm_bitreversal_f32(
57
    float32_t * pSrc,
58
    uint16_t fftSize,
59
    uint16_t bitRevFactor,
60
    uint16_t * pBitRevTab);
61
 
62
/**    
63
 * @ingroup groupTransforms    
64
 */
65
 
66
/*--------------------------------------------------------------------    
67
 *              Internal functions prototypes    
68
 *--------------------------------------------------------------------*/
69
 
70
void arm_split_rfft_f32(
71
  float32_t * pSrc,
72
  uint32_t fftLen,
73
  float32_t * pATable,
74
  float32_t * pBTable,
75
  float32_t * pDst,
76
  uint32_t modifier);
77
void arm_split_rifft_f32(
78
  float32_t * pSrc,
79
  uint32_t fftLen,
80
  float32_t * pATable,
81
  float32_t * pBTable,
82
  float32_t * pDst,
83
  uint32_t modifier);
84
 
85
/**    
86
 * @addtogroup RealFFT    
87
 * @{    
88
 */
89
 
90
/**    
91
 * @brief Processing function for the floating-point RFFT/RIFFT.  
92
 * @deprecated Do not use this function.  It has been superceded by \ref arm_rfft_fast_f32 and will be removed
93
 * in the future.
94
 * @param[in]  *S    points to an instance of the floating-point RFFT/RIFFT structure.  
95
 * @param[in]  *pSrc points to the input buffer.  
96
 * @param[out] *pDst points to the output buffer.  
97
 * @return none.  
98
 */
99
 
100
void arm_rfft_f32(
101
  const arm_rfft_instance_f32 * S,
102
  float32_t * pSrc,
103
  float32_t * pDst)
104
{
105
  const arm_cfft_radix4_instance_f32 *S_CFFT = S->pCfft;
106
 
107
 
108
  /* Calculation of Real IFFT of input */
109
  if(S->ifftFlagR == 1u)
110
  {
111
    /*  Real IFFT core process */
112
    arm_split_rifft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
113
                        S->pTwiddleBReal, pDst, S->twidCoefRModifier);
114
 
115
 
116
    /* Complex radix-4 IFFT process */
117
    arm_radix4_butterfly_inverse_f32(pDst, S_CFFT->fftLen,
118
                                     S_CFFT->pTwiddle,
119
                                     S_CFFT->twidCoefModifier,
120
                                     S_CFFT->onebyfftLen);
121
 
122
    /* Bit reversal process */
123
    if(S->bitReverseFlagR == 1u)
124
    {
125
      arm_bitreversal_f32(pDst, S_CFFT->fftLen,
126
                          S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
127
    }
128
  }
129
  else
130
  {
131
 
132
    /* Calculation of RFFT of input */
133
 
134
    /* Complex radix-4 FFT process */
135
    arm_radix4_butterfly_f32(pSrc, S_CFFT->fftLen,
136
                             S_CFFT->pTwiddle, S_CFFT->twidCoefModifier);
137
 
138
    /* Bit reversal process */
139
    if(S->bitReverseFlagR == 1u)
140
    {
141
      arm_bitreversal_f32(pSrc, S_CFFT->fftLen,
142
                          S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
143
    }
144
 
145
 
146
    /*  Real FFT core process */
147
    arm_split_rfft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
148
                       S->pTwiddleBReal, pDst, S->twidCoefRModifier);
149
  }
150
 
151
}
152
 
153
/**    
154
   * @} end of RealFFT group    
155
   */
156
 
157
/**    
158
 * @brief  Core Real FFT process    
159
 * @param[in]   *pSrc                           points to the input buffer.    
160
 * @param[in]   fftLen                          length of FFT.    
161
 * @param[in]   *pATable                        points to the twiddle Coef A buffer.    
162
 * @param[in]   *pBTable                        points to the twiddle Coef B buffer.    
163
 * @param[out]  *pDst                           points to the output buffer.    
164
 * @param[in]   modifier                twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.  
165
 * @return none.    
166
 */
167
 
168
void arm_split_rfft_f32(
169
  float32_t * pSrc,
170
  uint32_t fftLen,
171
  float32_t * pATable,
172
  float32_t * pBTable,
173
  float32_t * pDst,
174
  uint32_t modifier)
175
{
176
  uint32_t i;                                    /* Loop Counter */
177
  float32_t outR, outI;                          /* Temporary variables for output */
178
  float32_t *pCoefA, *pCoefB;                    /* Temporary pointers for twiddle factors */
179
  float32_t CoefA1, CoefA2, CoefB1;              /* Temporary variables for twiddle coefficients */
180
  float32_t *pDst1 = &pDst[2], *pDst2 = &pDst[(4u * fftLen) - 1u];      /* temp pointers for output buffer */
181
  float32_t *pSrc1 = &pSrc[2], *pSrc2 = &pSrc[(2u * fftLen) - 1u];      /* temp pointers for input buffer */
182
 
183
  /* Init coefficient pointers */
184
  pCoefA = &pATable[modifier * 2u];
185
  pCoefB = &pBTable[modifier * 2u];
186
 
187
  i = fftLen - 1u;
188
 
189
  while(i > 0u)
190
  {
191
    /*    
192
       outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]    
193
       + pSrc[2 * n - 2 * i] * pBTable[2 * i] +    
194
       pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);    
195
     */
196
 
197
    /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +    
198
       pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -    
199
       pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
200
 
201
    /* read pATable[2 * i] */
202
    CoefA1 = *pCoefA++;
203
    /* pATable[2 * i + 1] */
204
    CoefA2 = *pCoefA;
205
 
206
    /* pSrc[2 * i] * pATable[2 * i] */
207
    outR = *pSrc1 * CoefA1;
208
    /* pSrc[2 * i] * CoefA2 */
209
    outI = *pSrc1++ * CoefA2;
210
 
211
    /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
212
    outR -= (*pSrc1 + *pSrc2) * CoefA2;
213
    /* pSrc[2 * i + 1] * CoefA1 */
214
    outI += *pSrc1++ * CoefA1;
215
 
216
    CoefB1 = *pCoefB;
217
 
218
    /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
219
    outI -= *pSrc2-- * CoefB1;
220
    /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
221
    outI -= *pSrc2 * CoefA2;
222
 
223
    /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
224
    outR += *pSrc2-- * CoefB1;
225
 
226
    /* write output */
227
    *pDst1++ = outR;
228
    *pDst1++ = outI;
229
 
230
    /* write complex conjugate output */
231
    *pDst2-- = -outI;
232
    *pDst2-- = outR;
233
 
234
    /* update coefficient pointer */
235
    pCoefB = pCoefB + (modifier * 2u);
236
    pCoefA = pCoefA + ((modifier * 2u) - 1u);
237
 
238
    i--;
239
 
240
  }
241
 
242
  pDst[2u * fftLen] = pSrc[0] - pSrc[1];
243
  pDst[(2u * fftLen) + 1u] = 0.0f;
244
 
245
  pDst[0] = pSrc[0] + pSrc[1];
246
  pDst[1] = 0.0f;
247
 
248
}
249
 
250
 
251
/**    
252
 * @brief  Core Real IFFT process    
253
 * @param[in]   *pSrc                           points to the input buffer.    
254
 * @param[in]   fftLen                          length of FFT.  
255
 * @param[in]   *pATable                        points to the twiddle Coef A buffer.  
256
 * @param[in]   *pBTable                        points to the twiddle Coef B buffer.  
257
 * @param[out]  *pDst                           points to the output buffer.  
258
 * @param[in]   modifier                twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.    
259
 * @return none.    
260
 */
261
 
262
void arm_split_rifft_f32(
263
  float32_t * pSrc,
264
  uint32_t fftLen,
265
  float32_t * pATable,
266
  float32_t * pBTable,
267
  float32_t * pDst,
268
  uint32_t modifier)
269
{
270
  float32_t outR, outI;                          /* Temporary variables for output */
271
  float32_t *pCoefA, *pCoefB;                    /* Temporary pointers for twiddle factors */
272
  float32_t CoefA1, CoefA2, CoefB1;              /* Temporary variables for twiddle coefficients */
273
  float32_t *pSrc1 = &pSrc[0], *pSrc2 = &pSrc[(2u * fftLen) + 1u];
274
 
275
  pCoefA = &pATable[0];
276
  pCoefB = &pBTable[0];
277
 
278
  while(fftLen > 0u)
279
  {
280
    /*    
281
       outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +    
282
       pIn[2 * n - 2 * i] * pBTable[2 * i] -    
283
       pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);    
284
 
285
       outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -    
286
       pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -    
287
       pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);    
288
 
289
     */
290
 
291
    CoefA1 = *pCoefA++;
292
    CoefA2 = *pCoefA;
293
 
294
    /* outR = (pSrc[2 * i] * CoefA1 */
295
    outR = *pSrc1 * CoefA1;
296
 
297
    /* - pSrc[2 * i] * CoefA2 */
298
    outI = -(*pSrc1++) * CoefA2;
299
 
300
    /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
301
    outR += (*pSrc1 + *pSrc2) * CoefA2;
302
 
303
    /* pSrc[2 * i + 1] * CoefA1 */
304
    outI += (*pSrc1++) * CoefA1;
305
 
306
    CoefB1 = *pCoefB;
307
 
308
    /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
309
    outI -= *pSrc2-- * CoefB1;
310
 
311
    /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
312
    outR += *pSrc2 * CoefB1;
313
 
314
    /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
315
    outI += *pSrc2-- * CoefA2;
316
 
317
    /* write output */
318
    *pDst++ = outR;
319
    *pDst++ = outI;
320
 
321
    /* update coefficient pointer */
322
    pCoefB = pCoefB + (modifier * 2u);
323
    pCoefA = pCoefA + ((modifier * 2u) - 1u);
324
 
325
    /* Decrement loop count */
326
    fftLen--;
327
  }
328
 
329
}