Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | 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 | } |