arm_cfft_radix2_f32.c
1 /* ---------------------------------------------------------------------- 2 * Project: CMSIS DSP Library 3 * Title: arm_cfft_radix2_f32.c 4 * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function 5 * 6 * $Date: 23 April 2021 7 * $Revision: V1.9.0 8 * 9 * Target Processor: Cortex-M and Cortex-A cores 10 * -------------------------------------------------------------------- */ 11 /* 12 * Copyright (C) 2010-2021 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 "dsp/transform_functions.h" 30 31 void arm_radix2_butterfly_f32( 32 float32_t * pSrc, 33 uint32_t fftLen, 34 const float32_t * pCoef, 35 uint16_t twidCoefModifier); 36 37 void arm_radix2_butterfly_inverse_f32( 38 float32_t * pSrc, 39 uint32_t fftLen, 40 const float32_t * pCoef, 41 uint16_t twidCoefModifier, 42 float32_t onebyfftLen); 43 44 extern void arm_bitreversal_f32( 45 float32_t * pSrc, 46 uint16_t fftSize, 47 uint16_t bitRevFactor, 48 const uint16_t * pBitRevTab); 49 50 /** 51 @ingroup groupTransforms 52 */ 53 54 /** 55 @addtogroup ComplexFFT 56 @{ 57 */ 58 59 /** 60 @brief Radix-2 CFFT/CIFFT. 61 @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed in the future 62 @param[in] S points to an instance of the floating-point Radix-2 CFFT/CIFFT structure 63 @param[in,out] pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place 64 @return none 65 */ 66 67 void arm_cfft_radix2_f32( 68 const arm_cfft_radix2_instance_f32 * S, 69 float32_t * pSrc) 70 { 71 72 if (S->ifftFlag == 1U) 73 { 74 /* Complex IFFT radix-2 */ 75 arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle, 76 S->twidCoefModifier, S->onebyfftLen); 77 } 78 else 79 { 80 /* Complex FFT radix-2 */ 81 arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle, 82 S->twidCoefModifier); 83 } 84 85 if (S->bitReverseFlag == 1U) 86 { 87 /* Bit Reversal */ 88 arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); 89 } 90 91 } 92 93 94 /** 95 @} end of ComplexFFT group 96 */ 97 98 99 100 /* ---------------------------------------------------------------------- 101 ** Internal helper function used by the FFTs 102 ** ------------------------------------------------------------------- */ 103 104 /** 105 brief Core function for the floating-point CFFT butterfly process. 106 param[in,out] pSrc points to in-place buffer of floating-point data type 107 param[in] fftLen length of the FFT 108 param[in] pCoef points to twiddle coefficient buffer 109 param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table 110 return none 111 */ 112 113 void arm_radix2_butterfly_f32( 114 float32_t * pSrc, 115 uint32_t fftLen, 116 const float32_t * pCoef, 117 uint16_t twidCoefModifier) 118 { 119 120 uint32_t i, j, k, l; 121 uint32_t n1, n2, ia; 122 float32_t xt, yt, cosVal, sinVal; 123 float32_t p0, p1, p2, p3; 124 float32_t a0, a1; 125 126 #if defined (ARM_MATH_DSP) 127 128 /* Initializations for the first stage */ 129 n2 = fftLen >> 1; 130 ia = 0; 131 i = 0; 132 133 // loop for groups 134 for (k = n2; k > 0; k--) 135 { 136 cosVal = pCoef[ia * 2]; 137 sinVal = pCoef[(ia * 2) + 1]; 138 139 /* Twiddle coefficients index modifier */ 140 ia += twidCoefModifier; 141 142 /* index calculation for the input as, */ 143 /* pSrc[i + 0], pSrc[i + fftLen/1] */ 144 l = i + n2; 145 146 /* Butterfly implementation */ 147 a0 = pSrc[2 * i] + pSrc[2 * l]; 148 xt = pSrc[2 * i] - pSrc[2 * l]; 149 150 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 151 a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 152 153 p0 = xt * cosVal; 154 p1 = yt * sinVal; 155 p2 = yt * cosVal; 156 p3 = xt * sinVal; 157 158 pSrc[2 * i] = a0; 159 pSrc[2 * i + 1] = a1; 160 161 pSrc[2 * l] = p0 + p1; 162 pSrc[2 * l + 1] = p2 - p3; 163 164 i++; 165 } // groups loop end 166 167 twidCoefModifier <<= 1U; 168 169 // loop for stage 170 for (k = n2; k > 2; k = k >> 1) 171 { 172 n1 = n2; 173 n2 = n2 >> 1; 174 ia = 0; 175 176 // loop for groups 177 j = 0; 178 do 179 { 180 cosVal = pCoef[ia * 2]; 181 sinVal = pCoef[(ia * 2) + 1]; 182 ia += twidCoefModifier; 183 184 // loop for butterfly 185 i = j; 186 do 187 { 188 l = i + n2; 189 a0 = pSrc[2 * i] + pSrc[2 * l]; 190 xt = pSrc[2 * i] - pSrc[2 * l]; 191 192 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 193 a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 194 195 p0 = xt * cosVal; 196 p1 = yt * sinVal; 197 p2 = yt * cosVal; 198 p3 = xt * sinVal; 199 200 pSrc[2 * i] = a0; 201 pSrc[2 * i + 1] = a1; 202 203 pSrc[2 * l] = p0 + p1; 204 pSrc[2 * l + 1] = p2 - p3; 205 206 i += n1; 207 } while ( i < fftLen ); // butterfly loop end 208 j++; 209 } while ( j < n2); // groups loop end 210 twidCoefModifier <<= 1U; 211 } // stages loop end 212 213 // loop for butterfly 214 for (i = 0; i < fftLen; i += 2) 215 { 216 a0 = pSrc[2 * i] + pSrc[2 * i + 2]; 217 xt = pSrc[2 * i] - pSrc[2 * i + 2]; 218 219 yt = pSrc[2 * i + 1] - pSrc[2 * i + 3]; 220 a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1]; 221 222 pSrc[2 * i] = a0; 223 pSrc[2 * i + 1] = a1; 224 pSrc[2 * i + 2] = xt; 225 pSrc[2 * i + 3] = yt; 226 } // groups loop end 227 228 #else /* #if defined (ARM_MATH_DSP) */ 229 230 n2 = fftLen; 231 232 // loop for stage 233 for (k = fftLen; k > 1; k = k >> 1) 234 { 235 n1 = n2; 236 n2 = n2 >> 1; 237 ia = 0; 238 239 // loop for groups 240 j = 0; 241 do 242 { 243 cosVal = pCoef[ia * 2]; 244 sinVal = pCoef[(ia * 2) + 1]; 245 ia += twidCoefModifier; 246 247 // loop for butterfly 248 i = j; 249 do 250 { 251 l = i + n2; 252 a0 = pSrc[2 * i] + pSrc[2 * l]; 253 xt = pSrc[2 * i] - pSrc[2 * l]; 254 255 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 256 a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 257 258 p0 = xt * cosVal; 259 p1 = yt * sinVal; 260 p2 = yt * cosVal; 261 p3 = xt * sinVal; 262 263 pSrc[2 * i] = a0; 264 pSrc[2 * i + 1] = a1; 265 266 pSrc[2 * l] = p0 + p1; 267 pSrc[2 * l + 1] = p2 - p3; 268 269 i += n1; 270 } while (i < fftLen); 271 j++; 272 } while (j < n2); 273 twidCoefModifier <<= 1U; 274 } 275 276 #endif /* #if defined (ARM_MATH_DSP) */ 277 278 } 279 280 281 void arm_radix2_butterfly_inverse_f32( 282 float32_t * pSrc, 283 uint32_t fftLen, 284 const float32_t * pCoef, 285 uint16_t twidCoefModifier, 286 float32_t onebyfftLen) 287 { 288 289 uint32_t i, j, k, l; 290 uint32_t n1, n2, ia; 291 float32_t xt, yt, cosVal, sinVal; 292 float32_t p0, p1, p2, p3; 293 float32_t a0, a1; 294 295 #if defined (ARM_MATH_DSP) 296 297 n2 = fftLen >> 1; 298 ia = 0; 299 300 // loop for groups 301 for (i = 0; i < n2; i++) 302 { 303 cosVal = pCoef[ia * 2]; 304 sinVal = pCoef[(ia * 2) + 1]; 305 ia += twidCoefModifier; 306 307 l = i + n2; 308 a0 = pSrc[2 * i] + pSrc[2 * l]; 309 xt = pSrc[2 * i] - pSrc[2 * l]; 310 311 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 312 a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 313 314 p0 = xt * cosVal; 315 p1 = yt * sinVal; 316 p2 = yt * cosVal; 317 p3 = xt * sinVal; 318 319 pSrc[2 * i] = a0; 320 pSrc[2 * i + 1] = a1; 321 322 pSrc[2 * l] = p0 - p1; 323 pSrc[2 * l + 1] = p2 + p3; 324 } // groups loop end 325 326 twidCoefModifier <<= 1U; 327 328 // loop for stage 329 for (k = fftLen / 2; k > 2; k = k >> 1) 330 { 331 n1 = n2; 332 n2 = n2 >> 1; 333 ia = 0; 334 335 // loop for groups 336 j = 0; 337 do 338 { 339 cosVal = pCoef[ia * 2]; 340 sinVal = pCoef[(ia * 2) + 1]; 341 ia += twidCoefModifier; 342 343 // loop for butterfly 344 i = j; 345 do 346 { 347 l = i + n2; 348 a0 = pSrc[2 * i] + pSrc[2 * l]; 349 xt = pSrc[2 * i] - pSrc[2 * l]; 350 351 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 352 a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 353 354 p0 = xt * cosVal; 355 p1 = yt * sinVal; 356 p2 = yt * cosVal; 357 p3 = xt * sinVal; 358 359 pSrc[2 * i] = a0; 360 pSrc[2 * i + 1] = a1; 361 362 pSrc[2 * l] = p0 - p1; 363 pSrc[2 * l + 1] = p2 + p3; 364 365 i += n1; 366 } while ( i < fftLen ); // butterfly loop end 367 j++; 368 } while (j < n2); // groups loop end 369 370 twidCoefModifier <<= 1U; 371 } // stages loop end 372 373 // loop for butterfly 374 for (i = 0; i < fftLen; i += 2) 375 { 376 a0 = pSrc[2 * i] + pSrc[2 * i + 2]; 377 xt = pSrc[2 * i] - pSrc[2 * i + 2]; 378 379 a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1]; 380 yt = pSrc[2 * i + 1] - pSrc[2 * i + 3]; 381 382 p0 = a0 * onebyfftLen; 383 p2 = xt * onebyfftLen; 384 p1 = a1 * onebyfftLen; 385 p3 = yt * onebyfftLen; 386 387 pSrc[2 * i] = p0; 388 pSrc[2 * i + 1] = p1; 389 pSrc[2 * i + 2] = p2; 390 pSrc[2 * i + 3] = p3; 391 } // butterfly loop end 392 393 #else /* #if defined (ARM_MATH_DSP) */ 394 395 n2 = fftLen; 396 397 // loop for stage 398 for (k = fftLen; k > 2; k = k >> 1) 399 { 400 n1 = n2; 401 n2 = n2 >> 1; 402 ia = 0; 403 404 // loop for groups 405 j = 0; 406 do 407 { 408 cosVal = pCoef[ia * 2]; 409 sinVal = pCoef[(ia * 2) + 1]; 410 ia = ia + twidCoefModifier; 411 412 // loop for butterfly 413 i = j; 414 do 415 { 416 l = i + n2; 417 a0 = pSrc[2 * i] + pSrc[2 * l]; 418 xt = pSrc[2 * i] - pSrc[2 * l]; 419 420 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 421 a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 422 423 p0 = xt * cosVal; 424 p1 = yt * sinVal; 425 p2 = yt * cosVal; 426 p3 = xt * sinVal; 427 428 pSrc[2 * i] = a0; 429 pSrc[2 * i + 1] = a1; 430 431 pSrc[2 * l] = p0 - p1; 432 pSrc[2 * l + 1] = p2 + p3; 433 434 i += n1; 435 } while ( i < fftLen ); // butterfly loop end 436 j++; 437 } while ( j < n2 ); // groups loop end 438 439 twidCoefModifier = twidCoefModifier << 1U; 440 } // stages loop end 441 442 n1 = n2; 443 n2 = n2 >> 1; 444 445 // loop for butterfly 446 for (i = 0; i < fftLen; i += n1) 447 { 448 l = i + n2; 449 450 a0 = pSrc[2 * i] + pSrc[2 * l]; 451 xt = pSrc[2 * i] - pSrc[2 * l]; 452 453 a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 454 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 455 456 p0 = a0 * onebyfftLen; 457 p2 = xt * onebyfftLen; 458 p1 = a1 * onebyfftLen; 459 p3 = yt * onebyfftLen; 460 461 pSrc[2 * i] = p0; 462 pSrc[2 * l] = p2; 463 464 pSrc[2 * i + 1] = p1; 465 pSrc[2 * l + 1] = p3; 466 } // butterfly loop end 467 468 #endif /* #if defined (ARM_MATH_DSP) */ 469 470 }