1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
4 * $Date: 17. January 2013
7 * Project: CMSIS DSP Library
8 * Title: arm_cfft_radix2_q31.c
10 * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function
13 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * - Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * - Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in
22 * the documentation and/or other materials provided with the
24 * - Neither the name of ARM LIMITED nor the names of its contributors
25 * may be used to endorse or promote products derived from this
26 * software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 * -------------------------------------------------------------------- */
44 void arm_radix2_butterfly_q31(
48 uint16_t twidCoefModifier
);
50 void arm_radix2_butterfly_inverse_q31(
54 uint16_t twidCoefModifier
);
56 void arm_bitreversal_q31(
59 uint16_t bitRevFactor
,
60 uint16_t * pBitRevTab
);
63 * @ingroup groupTransforms
67 * @addtogroup ComplexFFT
73 * @brief Processing function for the fixed-point CFFT/CIFFT.
74 * @param[in] *S points to an instance of the fixed-point CFFT/CIFFT structure.
75 * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
79 void arm_cfft_radix2_q31(
80 const arm_cfft_radix2_instance_q31
* S
,
86 arm_radix2_butterfly_inverse_q31(pSrc
, S
->fftLen
,
87 S
->pTwiddle
, S
->twidCoefModifier
);
91 arm_radix2_butterfly_q31(pSrc
, S
->fftLen
,
92 S
->pTwiddle
, S
->twidCoefModifier
);
95 arm_bitreversal_q31(pSrc
, S
->fftLen
, S
->bitRevFactor
, S
->pBitRevTable
);
99 * @} end of ComplexFFT group
102 void arm_radix2_butterfly_q31(
106 uint16_t twidCoefModifier
)
109 unsigned i
, j
, k
, l
, m
;
111 q31_t xt
, yt
, cosVal
, sinVal
;
122 for (i
= 0; i
< n2
; i
++)
124 cosVal
= pCoef
[ia
* 2];
125 sinVal
= pCoef
[(ia
* 2) + 1];
126 ia
= ia
+ twidCoefModifier
;
129 xt
= (pSrc
[2 * i
] >> 2u) - (pSrc
[2 * l
] >> 2u);
130 pSrc
[2 * i
] = ((pSrc
[2 * i
] >> 2u) + (pSrc
[2 * l
] >> 2u)) >> 1u;
132 yt
= (pSrc
[2 * i
+ 1] >> 2u) - (pSrc
[2 * l
+ 1] >> 2u);
134 ((pSrc
[2 * l
+ 1] >> 2u) + (pSrc
[2 * i
+ 1] >> 2u)) >> 1u;
136 mult_32x32_keep32_R(p0
, xt
, cosVal
);
137 mult_32x32_keep32_R(p1
, yt
, cosVal
);
138 multAcc_32x32_keep32_R(p0
, yt
, sinVal
);
139 multSub_32x32_keep32_R(p1
, xt
, sinVal
);
142 pSrc
[2u * l
+ 1u] = p1
;
146 twidCoefModifier
<<= 1u;
149 for (k
= fftLen
/ 2; k
> 2; k
= k
>> 1)
156 for (j
= 0; j
< n2
; j
++)
158 cosVal
= pCoef
[ia
* 2];
159 sinVal
= pCoef
[(ia
* 2) + 1];
160 ia
= ia
+ twidCoefModifier
;
162 // loop for butterfly
168 xt
= pSrc
[2 * i
] - pSrc
[2 * l
];
169 pSrc
[2 * i
] = (pSrc
[2 * i
] + pSrc
[2 * l
]) >> 1u;
171 yt
= pSrc
[2 * i
+ 1] - pSrc
[2 * l
+ 1];
172 pSrc
[2 * i
+ 1] = (pSrc
[2 * l
+ 1] + pSrc
[2 * i
+ 1]) >> 1u;
174 mult_32x32_keep32_R(p0
, xt
, cosVal
);
175 mult_32x32_keep32_R(p1
, yt
, cosVal
);
176 multAcc_32x32_keep32_R(p0
, yt
, sinVal
);
177 multSub_32x32_keep32_R(p1
, xt
, sinVal
);
180 pSrc
[2u * l
+ 1u] = p1
;
183 } while( m
> 0); // butterfly loop end
187 twidCoefModifier
<<= 1u;
194 cosVal
= pCoef
[ia
* 2];
195 sinVal
= pCoef
[(ia
* 2) + 1];
196 ia
= ia
+ twidCoefModifier
;
198 // loop for butterfly
199 for (i
= 0; i
< fftLen
; i
+= n1
)
202 xt
= pSrc
[2 * i
] - pSrc
[2 * l
];
203 pSrc
[2 * i
] = (pSrc
[2 * i
] + pSrc
[2 * l
]);
205 yt
= pSrc
[2 * i
+ 1] - pSrc
[2 * l
+ 1];
206 pSrc
[2 * i
+ 1] = (pSrc
[2 * l
+ 1] + pSrc
[2 * i
+ 1]);
210 pSrc
[2u * l
+ 1u] = yt
;
215 xt
= pSrc
[2 * i
] - pSrc
[2 * l
];
216 pSrc
[2 * i
] = (pSrc
[2 * i
] + pSrc
[2 * l
]);
218 yt
= pSrc
[2 * i
+ 1] - pSrc
[2 * l
+ 1];
219 pSrc
[2 * i
+ 1] = (pSrc
[2 * l
+ 1] + pSrc
[2 * i
+ 1]);
223 pSrc
[2u * l
+ 1u] = yt
;
225 } // butterfly loop end
230 void arm_radix2_butterfly_inverse_q31(
234 uint16_t twidCoefModifier
)
239 q31_t xt
, yt
, cosVal
, sinVal
;
250 for (i
= 0; i
< n2
; i
++)
252 cosVal
= pCoef
[ia
* 2];
253 sinVal
= pCoef
[(ia
* 2) + 1];
254 ia
= ia
+ twidCoefModifier
;
257 xt
= (pSrc
[2 * i
] >> 2u) - (pSrc
[2 * l
] >> 2u);
258 pSrc
[2 * i
] = ((pSrc
[2 * i
] >> 2u) + (pSrc
[2 * l
] >> 2u)) >> 1u;
260 yt
= (pSrc
[2 * i
+ 1] >> 2u) - (pSrc
[2 * l
+ 1] >> 2u);
262 ((pSrc
[2 * l
+ 1] >> 2u) + (pSrc
[2 * i
+ 1] >> 2u)) >> 1u;
264 mult_32x32_keep32_R(p0
, xt
, cosVal
);
265 mult_32x32_keep32_R(p1
, yt
, cosVal
);
266 multSub_32x32_keep32_R(p0
, yt
, sinVal
);
267 multAcc_32x32_keep32_R(p1
, xt
, sinVal
);
270 pSrc
[2u * l
+ 1u] = p1
;
273 twidCoefModifier
= twidCoefModifier
<< 1u;
276 for (k
= fftLen
/ 2; k
> 2; k
= k
>> 1)
283 for (j
= 0; j
< n2
; j
++)
285 cosVal
= pCoef
[ia
* 2];
286 sinVal
= pCoef
[(ia
* 2) + 1];
287 ia
= ia
+ twidCoefModifier
;
289 // loop for butterfly
290 for (i
= j
; i
< fftLen
; i
+= n1
)
293 xt
= pSrc
[2 * i
] - pSrc
[2 * l
];
294 pSrc
[2 * i
] = (pSrc
[2 * i
] + pSrc
[2 * l
]) >> 1u;
296 yt
= pSrc
[2 * i
+ 1] - pSrc
[2 * l
+ 1];
297 pSrc
[2 * i
+ 1] = (pSrc
[2 * l
+ 1] + pSrc
[2 * i
+ 1]) >> 1u;
299 mult_32x32_keep32_R(p0
, xt
, cosVal
);
300 mult_32x32_keep32_R(p1
, yt
, cosVal
);
301 multSub_32x32_keep32_R(p0
, yt
, sinVal
);
302 multAcc_32x32_keep32_R(p1
, xt
, sinVal
);
305 pSrc
[2u * l
+ 1u] = p1
;
306 } // butterfly loop end
310 twidCoefModifier
= twidCoefModifier
<< 1u;
317 cosVal
= pCoef
[ia
* 2];
318 sinVal
= pCoef
[(ia
* 2) + 1];
319 ia
= ia
+ twidCoefModifier
;
321 // loop for butterfly
322 for (i
= 0; i
< fftLen
; i
+= n1
)
325 xt
= pSrc
[2 * i
] - pSrc
[2 * l
];
326 pSrc
[2 * i
] = (pSrc
[2 * i
] + pSrc
[2 * l
]);
328 yt
= pSrc
[2 * i
+ 1] - pSrc
[2 * l
+ 1];
329 pSrc
[2 * i
+ 1] = (pSrc
[2 * l
+ 1] + pSrc
[2 * i
+ 1]);
333 pSrc
[2u * l
+ 1u] = yt
;
338 xt
= pSrc
[2 * i
] - pSrc
[2 * l
];
339 pSrc
[2 * i
] = (pSrc
[2 * i
] + pSrc
[2 * l
]);
341 yt
= pSrc
[2 * i
+ 1] - pSrc
[2 * l
+ 1];
342 pSrc
[2 * i
+ 1] = (pSrc
[2 * l
+ 1] + pSrc
[2 * i
+ 1]);
346 pSrc
[2u * l
+ 1u] = yt
;
348 } // butterfly loop end