QuakeGod
2021-06-20 bfc108e6097eff2bec73050e261f3b9e5db447b7
提交 | 用户 | age
bfc108 1 /* ----------------------------------------------------------------------    
Q 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 }