1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_rfft_f32.c
4 * Description: RFFT & RIFFT Floating point process function
6 * $Date: 27. January 2017
9 * Target Processor: Cortex-M cores
10 * -------------------------------------------------------------------- */
12 * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
14 * SPDX-License-Identifier: Apache-2.0
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
20 * www.apache.org/licenses/LICENSE-2.0
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.
31 /* ----------------------------------------------------------------------
32 * Internal functions prototypes
33 * -------------------------------------------------------------------- */
35 extern void arm_radix4_butterfly_f32(
39 uint16_t twidCoefModifier
);
41 extern void arm_radix4_butterfly_inverse_f32(
45 uint16_t twidCoefModifier
,
46 float32_t onebyfftLen
);
48 extern void arm_bitreversal_f32(
51 uint16_t bitRevFactor
,
52 uint16_t * pBitRevTab
);
54 void arm_split_rfft_f32(
62 void arm_split_rifft_f32(
71 * @ingroup groupTransforms
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
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.
90 const arm_rfft_instance_f32
* S
,
94 const arm_cfft_radix4_instance_f32
*S_CFFT
= S
->pCfft
;
97 /* Calculation of Real IFFT of input */
98 if (S
->ifftFlagR
== 1U)
100 /* Real IFFT core process */
101 arm_split_rifft_f32(pSrc
, S
->fftLenBy2
, S
->pTwiddleAReal
,
102 S
->pTwiddleBReal
, pDst
, S
->twidCoefRModifier
);
105 /* Complex radix-4 IFFT process */
106 arm_radix4_butterfly_inverse_f32(pDst
, S_CFFT
->fftLen
,
108 S_CFFT
->twidCoefModifier
,
109 S_CFFT
->onebyfftLen
);
111 /* Bit reversal process */
112 if (S
->bitReverseFlagR
== 1U)
114 arm_bitreversal_f32(pDst
, S_CFFT
->fftLen
,
115 S_CFFT
->bitRevFactor
, S_CFFT
->pBitRevTable
);
121 /* Calculation of RFFT of input */
123 /* Complex radix-4 FFT process */
124 arm_radix4_butterfly_f32(pSrc
, S_CFFT
->fftLen
,
125 S_CFFT
->pTwiddle
, S_CFFT
->twidCoefModifier
);
127 /* Bit reversal process */
128 if (S
->bitReverseFlagR
== 1U)
130 arm_bitreversal_f32(pSrc
, S_CFFT
->fftLen
,
131 S_CFFT
->bitRevFactor
, S_CFFT
->pBitRevTable
);
135 /* Real FFT core process */
136 arm_split_rfft_f32(pSrc
, S
->fftLenBy2
, S
->pTwiddleAReal
,
137 S
->pTwiddleBReal
, pDst
, S
->twidCoefRModifier
);
143 * @} end of RealFFT group
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.
157 void arm_split_rfft_f32(
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 */
172 /* Init coefficient pointers */
173 pCoefA
= &pATable
[modifier
* 2U];
174 pCoefB
= &pBTable
[modifier
* 2U];
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]);
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]); */
190 /* read pATable[2 * i] */
192 /* pATable[2 * i + 1] */
195 /* pSrc[2 * i] * pATable[2 * i] */
196 outR
= *pSrc1
* CoefA1
;
197 /* pSrc[2 * i] * CoefA2 */
198 outI
= *pSrc1
++ * CoefA2
;
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
;
207 /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
208 outI
-= *pSrc2
-- * CoefB1
;
209 /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
210 outI
-= *pSrc2
* CoefA2
;
212 /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
213 outR
+= *pSrc2
-- * CoefB1
;
219 /* write complex conjugate output */
223 /* update coefficient pointer */
224 pCoefB
= pCoefB
+ (modifier
* 2U);
225 pCoefA
= pCoefA
+ ((modifier
* 2U) - 1U);
231 pDst
[2U * fftLen
] = pSrc
[0] - pSrc
[1];
232 pDst
[(2U * fftLen
) + 1U] = 0.0f
;
234 pDst
[0] = pSrc
[0] + pSrc
[1];
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.
251 void arm_split_rifft_f32(
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];
264 pCoefA
= &pATable
[0];
265 pCoefB
= &pBTable
[0];
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]);
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]);
283 /* outR = (pSrc[2 * i] * CoefA1 */
284 outR
= *pSrc1
* CoefA1
;
286 /* - pSrc[2 * i] * CoefA2 */
287 outI
= -(*pSrc1
++) * CoefA2
;
289 /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
290 outR
+= (*pSrc1
+ *pSrc2
) * CoefA2
;
292 /* pSrc[2 * i + 1] * CoefA1 */
293 outI
+= (*pSrc1
++) * CoefA1
;
297 /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
298 outI
-= *pSrc2
-- * CoefB1
;
300 /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
301 outR
+= *pSrc2
* CoefB1
;
303 /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
304 outI
+= *pSrc2
-- * CoefA2
;
310 /* update coefficient pointer */
311 pCoefB
= pCoefB
+ (modifier
* 2U);
312 pCoefA
= pCoefA
+ ((modifier
* 2U) - 1U);
314 /* Decrement loop count */