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