Subversion Repositories DashDisplay

Rev

Details | Last modification | View Log | RSS feed

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