1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
4 * $Date: 17. January 2013
7 * Project: CMSIS DSP Library
8 * Title: arm_rfft_f32.c
10 * Description: RFFT & RIFFT Floating point process function
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
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
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.
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 * -------------------------------------------------------------------- */
43 extern void arm_radix4_butterfly_f32(
47 uint16_t twidCoefModifier
);
49 extern void arm_radix4_butterfly_inverse_f32(
53 uint16_t twidCoefModifier
,
54 float32_t onebyfftLen
);
56 extern void arm_bitreversal_f32(
59 uint16_t bitRevFactor
,
60 uint16_t * pBitRevTab
);
63 * @ingroup groupTransforms
66 /*--------------------------------------------------------------------
67 * Internal functions prototypes
68 *--------------------------------------------------------------------*/
70 void arm_split_rfft_f32(
77 void arm_split_rifft_f32(
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
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.
101 const arm_rfft_instance_f32
* S
,
105 const arm_cfft_radix4_instance_f32
*S_CFFT
= S
->pCfft
;
108 /* Calculation of Real IFFT of input */
109 if(S
->ifftFlagR
== 1u)
111 /* Real IFFT core process */
112 arm_split_rifft_f32(pSrc
, S
->fftLenBy2
, S
->pTwiddleAReal
,
113 S
->pTwiddleBReal
, pDst
, S
->twidCoefRModifier
);
116 /* Complex radix-4 IFFT process */
117 arm_radix4_butterfly_inverse_f32(pDst
, S_CFFT
->fftLen
,
119 S_CFFT
->twidCoefModifier
,
120 S_CFFT
->onebyfftLen
);
122 /* Bit reversal process */
123 if(S
->bitReverseFlagR
== 1u)
125 arm_bitreversal_f32(pDst
, S_CFFT
->fftLen
,
126 S_CFFT
->bitRevFactor
, S_CFFT
->pBitRevTable
);
132 /* Calculation of RFFT of input */
134 /* Complex radix-4 FFT process */
135 arm_radix4_butterfly_f32(pSrc
, S_CFFT
->fftLen
,
136 S_CFFT
->pTwiddle
, S_CFFT
->twidCoefModifier
);
138 /* Bit reversal process */
139 if(S
->bitReverseFlagR
== 1u)
141 arm_bitreversal_f32(pSrc
, S_CFFT
->fftLen
,
142 S_CFFT
->bitRevFactor
, S_CFFT
->pBitRevTable
);
146 /* Real FFT core process */
147 arm_split_rfft_f32(pSrc
, S
->fftLenBy2
, S
->pTwiddleAReal
,
148 S
->pTwiddleBReal
, pDst
, S
->twidCoefRModifier
);
154 * @} end of RealFFT group
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.
168 void arm_split_rfft_f32(
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 */
183 /* Init coefficient pointers */
184 pCoefA
= &pATable
[modifier
* 2u];
185 pCoefB
= &pBTable
[modifier
* 2u];
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]);
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]); */
201 /* read pATable[2 * i] */
203 /* pATable[2 * i + 1] */
206 /* pSrc[2 * i] * pATable[2 * i] */
207 outR
= *pSrc1
* CoefA1
;
208 /* pSrc[2 * i] * CoefA2 */
209 outI
= *pSrc1
++ * CoefA2
;
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
;
218 /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
219 outI
-= *pSrc2
-- * CoefB1
;
220 /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
221 outI
-= *pSrc2
* CoefA2
;
223 /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
224 outR
+= *pSrc2
-- * CoefB1
;
230 /* write complex conjugate output */
234 /* update coefficient pointer */
235 pCoefB
= pCoefB
+ (modifier
* 2u);
236 pCoefA
= pCoefA
+ ((modifier
* 2u) - 1u);
242 pDst
[2u * fftLen
] = pSrc
[0] - pSrc
[1];
243 pDst
[(2u * fftLen
) + 1u] = 0.0f
;
245 pDst
[0] = pSrc
[0] + pSrc
[1];
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.
262 void arm_split_rifft_f32(
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];
275 pCoefA
= &pATable
[0];
276 pCoefB
= &pBTable
[0];
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]);
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]);
294 /* outR = (pSrc[2 * i] * CoefA1 */
295 outR
= *pSrc1
* CoefA1
;
297 /* - pSrc[2 * i] * CoefA2 */
298 outI
= -(*pSrc1
++) * CoefA2
;
300 /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
301 outR
+= (*pSrc1
+ *pSrc2
) * CoefA2
;
303 /* pSrc[2 * i + 1] * CoefA1 */
304 outI
+= (*pSrc1
++) * CoefA1
;
308 /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
309 outI
-= *pSrc2
-- * CoefB1
;
311 /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
312 outR
+= *pSrc2
* CoefB1
;
314 /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
315 outI
+= *pSrc2
-- * CoefA2
;
321 /* update coefficient pointer */
322 pCoefB
= pCoefB
+ (modifier
* 2u);
323 pCoefA
= pCoefA
+ ((modifier
* 2u) - 1u);
325 /* Decrement loop count */