Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
arm_cfft_radix8_f32.c
00001 /* ---------------------------------------------------------------------- 00002 * Copyright (C) 2010-2014 ARM Limited. All rights reserved. 00003 * 00004 * $Date: 19. March 2015 00005 * $Revision: V.1.4.5 00006 * 00007 * Project: CMSIS DSP Library 00008 * Title: arm_cfft_radix8_f32.c 00009 * 00010 * Description: Radix-8 Decimation in Frequency CFFT & CIFFT Floating point processing function 00011 * 00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 00013 * 00014 * Redistribution and use in source and binary forms, with or without 00015 * modification, are permitted provided that the following conditions 00016 * are met: 00017 * - Redistributions of source code must retain the above copyright 00018 * notice, this list of conditions and the following disclaimer. 00019 * - Redistributions in binary form must reproduce the above copyright 00020 * notice, this list of conditions and the following disclaimer in 00021 * the documentation and/or other materials provided with the 00022 * distribution. 00023 * - Neither the name of ARM LIMITED nor the names of its contributors 00024 * may be used to endorse or promote products derived from this 00025 * software without specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00028 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00029 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00030 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00031 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00032 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00033 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00034 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00035 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00036 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00037 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00038 * POSSIBILITY OF SUCH DAMAGE. 00039 * -------------------------------------------------------------------- */ 00040 00041 #include "arm_math.h" 00042 00043 /** 00044 * @ingroup groupTransforms 00045 */ 00046 00047 /** 00048 * @defgroup Radix8_CFFT_CIFFT Radix-8 Complex FFT Functions 00049 * 00050 * \par 00051 * Complex Fast Fourier Transform(CFFT) and Complex Inverse Fast Fourier Transform(CIFFT) is an efficient algorithm to compute Discrete Fourier Transform(DFT) and Inverse Discrete Fourier Transform(IDFT). 00052 * Computational complexity of CFFT reduces drastically when compared to DFT. 00053 * \par 00054 * This set of functions implements CFFT/CIFFT 00055 * for floating-point data types. The functions operates on in-place buffer which uses same buffer for input and output. 00056 * Complex input is stored in input buffer in an interleaved fashion. 00057 * 00058 * \par 00059 * The functions operate on blocks of input and output data and each call to the function processes 00060 * <code>2*fftLen</code> samples through the transform. <code>pSrc</code> points to In-place arrays containing <code>2*fftLen</code> values. 00061 * \par 00062 * The <code>pSrc</code> points to the array of in-place buffer of size <code>2*fftLen</code> and inputs and outputs are stored in an interleaved fashion as shown below. 00063 * <pre> {real[0], imag[0], real[1], imag[1],..} </pre> 00064 * 00065 * \par Lengths supported by the transform: 00066 * \par 00067 * Internally, the function utilize a Radix-8 decimation in frequency(DIF) algorithm 00068 * and the size of the FFT supported are of the lengths [ 64, 512, 4096]. 00069 * 00070 * 00071 * \par Algorithm: 00072 * 00073 * <b>Complex Fast Fourier Transform:</b> 00074 * \par 00075 * Input real and imaginary data: 00076 * <pre> 00077 * x(n) = xa + j * ya 00078 * x(n+N/4 ) = xb + j * yb 00079 * x(n+N/2 ) = xc + j * yc 00080 * x(n+3N 4) = xd + j * yd 00081 * </pre> 00082 * where N is length of FFT 00083 * \par 00084 * Output real and imaginary data: 00085 * <pre> 00086 * X(4r) = xa'+ j * ya' 00087 * X(4r+1) = xb'+ j * yb' 00088 * X(4r+2) = xc'+ j * yc' 00089 * X(4r+3) = xd'+ j * yd' 00090 * </pre> 00091 * \par 00092 * Twiddle factors for Radix-8 FFT: 00093 * <pre> 00094 * Wn = co1 + j * (- si1) 00095 * W2n = co2 + j * (- si2) 00096 * W3n = co3 + j * (- si3) 00097 * </pre> 00098 * 00099 * \par 00100 * \image html CFFT.gif "Radix-8 Decimation-in Frequency Complex Fast Fourier Transform" 00101 * 00102 * \par 00103 * Output from Radix-8 CFFT Results in Digit reversal order. Interchange middle two branches of every butterfly results in Bit reversed output. 00104 * \par 00105 * <b> Butterfly CFFT equations:</b> 00106 * <pre> 00107 * xa' = xa + xb + xc + xd 00108 * ya' = ya + yb + yc + yd 00109 * xc' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) 00110 * yc' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) 00111 * xb' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) 00112 * yb' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) 00113 * xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) 00114 * yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) 00115 * </pre> 00116 * 00117 * \par 00118 * where <code>fftLen</code> length of CFFT/CIFFT; <code>ifftFlag</code> Flag for selection of CFFT or CIFFT(Set ifftFlag to calculate CIFFT otherwise calculates CFFT); 00119 * <code>bitReverseFlag</code> Flag for selection of output order(Set bitReverseFlag to output in normal order otherwise output in bit reversed order); 00120 * <code>pTwiddle</code>points to array of twiddle coefficients; <code>pBitRevTable</code> points to the array of bit reversal table. 00121 * <code>twidCoefModifier</code> modifier for twiddle factor table which supports all FFT lengths with same table; 00122 * <code>pBitRevTable</code> modifier for bit reversal table which supports all FFT lengths with same table. 00123 * <code>onebyfftLen</code> value of 1/fftLen to calculate CIFFT; 00124 * 00125 * \par Fixed-Point Behavior 00126 * Care must be taken when using the fixed-point versions of the CFFT/CIFFT function. 00127 * Refer to the function specific documentation below for usage guidelines. 00128 */ 00129 00130 00131 /* 00132 * @brief Core function for the floating-point CFFT butterfly process. 00133 * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. 00134 * @param[in] fftLen length of the FFT. 00135 * @param[in] *pCoef points to the twiddle coefficient buffer. 00136 * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00137 * @return none. 00138 */ 00139 00140 void arm_radix8_butterfly_f32( 00141 float32_t * pSrc, 00142 uint16_t fftLen, 00143 const float32_t * pCoef, 00144 uint16_t twidCoefModifier) 00145 { 00146 uint32_t ia1, ia2, ia3, ia4, ia5, ia6, ia7; 00147 uint32_t i1, i2, i3, i4, i5, i6, i7, i8; 00148 uint32_t id; 00149 uint32_t n1, n2, j; 00150 00151 float32_t r1, r2, r3, r4, r5, r6, r7, r8; 00152 float32_t t1, t2; 00153 float32_t s1, s2, s3, s4, s5, s6, s7, s8; 00154 float32_t p1, p2, p3, p4; 00155 float32_t co2, co3, co4, co5, co6, co7, co8; 00156 float32_t si2, si3, si4, si5, si6, si7, si8; 00157 const float32_t C81 = 0.70710678118f; 00158 00159 n2 = fftLen; 00160 00161 do 00162 { 00163 n1 = n2; 00164 n2 = n2 >> 3; 00165 i1 = 0; 00166 00167 do 00168 { 00169 i2 = i1 + n2; 00170 i3 = i2 + n2; 00171 i4 = i3 + n2; 00172 i5 = i4 + n2; 00173 i6 = i5 + n2; 00174 i7 = i6 + n2; 00175 i8 = i7 + n2; 00176 r1 = pSrc[2 * i1] + pSrc[2 * i5]; 00177 r5 = pSrc[2 * i1] - pSrc[2 * i5]; 00178 r2 = pSrc[2 * i2] + pSrc[2 * i6]; 00179 r6 = pSrc[2 * i2] - pSrc[2 * i6]; 00180 r3 = pSrc[2 * i3] + pSrc[2 * i7]; 00181 r7 = pSrc[2 * i3] - pSrc[2 * i7]; 00182 r4 = pSrc[2 * i4] + pSrc[2 * i8]; 00183 r8 = pSrc[2 * i4] - pSrc[2 * i8]; 00184 t1 = r1 - r3; 00185 r1 = r1 + r3; 00186 r3 = r2 - r4; 00187 r2 = r2 + r4; 00188 pSrc[2 * i1] = r1 + r2; 00189 pSrc[2 * i5] = r1 - r2; 00190 r1 = pSrc[2 * i1 + 1] + pSrc[2 * i5 + 1]; 00191 s5 = pSrc[2 * i1 + 1] - pSrc[2 * i5 + 1]; 00192 r2 = pSrc[2 * i2 + 1] + pSrc[2 * i6 + 1]; 00193 s6 = pSrc[2 * i2 + 1] - pSrc[2 * i6 + 1]; 00194 s3 = pSrc[2 * i3 + 1] + pSrc[2 * i7 + 1]; 00195 s7 = pSrc[2 * i3 + 1] - pSrc[2 * i7 + 1]; 00196 r4 = pSrc[2 * i4 + 1] + pSrc[2 * i8 + 1]; 00197 s8 = pSrc[2 * i4 + 1] - pSrc[2 * i8 + 1]; 00198 t2 = r1 - s3; 00199 r1 = r1 + s3; 00200 s3 = r2 - r4; 00201 r2 = r2 + r4; 00202 pSrc[2 * i1 + 1] = r1 + r2; 00203 pSrc[2 * i5 + 1] = r1 - r2; 00204 pSrc[2 * i3] = t1 + s3; 00205 pSrc[2 * i7] = t1 - s3; 00206 pSrc[2 * i3 + 1] = t2 - r3; 00207 pSrc[2 * i7 + 1] = t2 + r3; 00208 r1 = (r6 - r8) * C81; 00209 r6 = (r6 + r8) * C81; 00210 r2 = (s6 - s8) * C81; 00211 s6 = (s6 + s8) * C81; 00212 t1 = r5 - r1; 00213 r5 = r5 + r1; 00214 r8 = r7 - r6; 00215 r7 = r7 + r6; 00216 t2 = s5 - r2; 00217 s5 = s5 + r2; 00218 s8 = s7 - s6; 00219 s7 = s7 + s6; 00220 pSrc[2 * i2] = r5 + s7; 00221 pSrc[2 * i8] = r5 - s7; 00222 pSrc[2 * i6] = t1 + s8; 00223 pSrc[2 * i4] = t1 - s8; 00224 pSrc[2 * i2 + 1] = s5 - r7; 00225 pSrc[2 * i8 + 1] = s5 + r7; 00226 pSrc[2 * i6 + 1] = t2 - r8; 00227 pSrc[2 * i4 + 1] = t2 + r8; 00228 00229 i1 += n1; 00230 } while(i1 < fftLen); 00231 00232 if(n2 < 8) 00233 break; 00234 00235 ia1 = 0; 00236 j = 1; 00237 00238 do 00239 { 00240 /* index calculation for the coefficients */ 00241 id = ia1 + twidCoefModifier; 00242 ia1 = id; 00243 ia2 = ia1 + id; 00244 ia3 = ia2 + id; 00245 ia4 = ia3 + id; 00246 ia5 = ia4 + id; 00247 ia6 = ia5 + id; 00248 ia7 = ia6 + id; 00249 00250 co2 = pCoef[2 * ia1]; 00251 co3 = pCoef[2 * ia2]; 00252 co4 = pCoef[2 * ia3]; 00253 co5 = pCoef[2 * ia4]; 00254 co6 = pCoef[2 * ia5]; 00255 co7 = pCoef[2 * ia6]; 00256 co8 = pCoef[2 * ia7]; 00257 si2 = pCoef[2 * ia1 + 1]; 00258 si3 = pCoef[2 * ia2 + 1]; 00259 si4 = pCoef[2 * ia3 + 1]; 00260 si5 = pCoef[2 * ia4 + 1]; 00261 si6 = pCoef[2 * ia5 + 1]; 00262 si7 = pCoef[2 * ia6 + 1]; 00263 si8 = pCoef[2 * ia7 + 1]; 00264 00265 i1 = j; 00266 00267 do 00268 { 00269 /* index calculation for the input */ 00270 i2 = i1 + n2; 00271 i3 = i2 + n2; 00272 i4 = i3 + n2; 00273 i5 = i4 + n2; 00274 i6 = i5 + n2; 00275 i7 = i6 + n2; 00276 i8 = i7 + n2; 00277 r1 = pSrc[2 * i1] + pSrc[2 * i5]; 00278 r5 = pSrc[2 * i1] - pSrc[2 * i5]; 00279 r2 = pSrc[2 * i2] + pSrc[2 * i6]; 00280 r6 = pSrc[2 * i2] - pSrc[2 * i6]; 00281 r3 = pSrc[2 * i3] + pSrc[2 * i7]; 00282 r7 = pSrc[2 * i3] - pSrc[2 * i7]; 00283 r4 = pSrc[2 * i4] + pSrc[2 * i8]; 00284 r8 = pSrc[2 * i4] - pSrc[2 * i8]; 00285 t1 = r1 - r3; 00286 r1 = r1 + r3; 00287 r3 = r2 - r4; 00288 r2 = r2 + r4; 00289 pSrc[2 * i1] = r1 + r2; 00290 r2 = r1 - r2; 00291 s1 = pSrc[2 * i1 + 1] + pSrc[2 * i5 + 1]; 00292 s5 = pSrc[2 * i1 + 1] - pSrc[2 * i5 + 1]; 00293 s2 = pSrc[2 * i2 + 1] + pSrc[2 * i6 + 1]; 00294 s6 = pSrc[2 * i2 + 1] - pSrc[2 * i6 + 1]; 00295 s3 = pSrc[2 * i3 + 1] + pSrc[2 * i7 + 1]; 00296 s7 = pSrc[2 * i3 + 1] - pSrc[2 * i7 + 1]; 00297 s4 = pSrc[2 * i4 + 1] + pSrc[2 * i8 + 1]; 00298 s8 = pSrc[2 * i4 + 1] - pSrc[2 * i8 + 1]; 00299 t2 = s1 - s3; 00300 s1 = s1 + s3; 00301 s3 = s2 - s4; 00302 s2 = s2 + s4; 00303 r1 = t1 + s3; 00304 t1 = t1 - s3; 00305 pSrc[2 * i1 + 1] = s1 + s2; 00306 s2 = s1 - s2; 00307 s1 = t2 - r3; 00308 t2 = t2 + r3; 00309 p1 = co5 * r2; 00310 p2 = si5 * s2; 00311 p3 = co5 * s2; 00312 p4 = si5 * r2; 00313 pSrc[2 * i5] = p1 + p2; 00314 pSrc[2 * i5 + 1] = p3 - p4; 00315 p1 = co3 * r1; 00316 p2 = si3 * s1; 00317 p3 = co3 * s1; 00318 p4 = si3 * r1; 00319 pSrc[2 * i3] = p1 + p2; 00320 pSrc[2 * i3 + 1] = p3 - p4; 00321 p1 = co7 * t1; 00322 p2 = si7 * t2; 00323 p3 = co7 * t2; 00324 p4 = si7 * t1; 00325 pSrc[2 * i7] = p1 + p2; 00326 pSrc[2 * i7 + 1] = p3 - p4; 00327 r1 = (r6 - r8) * C81; 00328 r6 = (r6 + r8) * C81; 00329 s1 = (s6 - s8) * C81; 00330 s6 = (s6 + s8) * C81; 00331 t1 = r5 - r1; 00332 r5 = r5 + r1; 00333 r8 = r7 - r6; 00334 r7 = r7 + r6; 00335 t2 = s5 - s1; 00336 s5 = s5 + s1; 00337 s8 = s7 - s6; 00338 s7 = s7 + s6; 00339 r1 = r5 + s7; 00340 r5 = r5 - s7; 00341 r6 = t1 + s8; 00342 t1 = t1 - s8; 00343 s1 = s5 - r7; 00344 s5 = s5 + r7; 00345 s6 = t2 - r8; 00346 t2 = t2 + r8; 00347 p1 = co2 * r1; 00348 p2 = si2 * s1; 00349 p3 = co2 * s1; 00350 p4 = si2 * r1; 00351 pSrc[2 * i2] = p1 + p2; 00352 pSrc[2 * i2 + 1] = p3 - p4; 00353 p1 = co8 * r5; 00354 p2 = si8 * s5; 00355 p3 = co8 * s5; 00356 p4 = si8 * r5; 00357 pSrc[2 * i8] = p1 + p2; 00358 pSrc[2 * i8 + 1] = p3 - p4; 00359 p1 = co6 * r6; 00360 p2 = si6 * s6; 00361 p3 = co6 * s6; 00362 p4 = si6 * r6; 00363 pSrc[2 * i6] = p1 + p2; 00364 pSrc[2 * i6 + 1] = p3 - p4; 00365 p1 = co4 * t1; 00366 p2 = si4 * t2; 00367 p3 = co4 * t2; 00368 p4 = si4 * t1; 00369 pSrc[2 * i4] = p1 + p2; 00370 pSrc[2 * i4 + 1] = p3 - p4; 00371 00372 i1 += n1; 00373 } while(i1 < fftLen); 00374 00375 j++; 00376 } while(j < n2); 00377 00378 twidCoefModifier <<= 3; 00379 } while(n2 > 7); 00380 } 00381 00382 /** 00383 * @} end of Radix8_CFFT_CIFFT group 00384 */
Generated on Fri Jul 22 2022 04:53:43 by
1.7.2
