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 mbed-os by
arm_cfft_q15.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_q15.c 00009 * 00010 * Description: Combined Radix Decimation in Q15 Frequency CFFT 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 extern void arm_radix4_butterfly_q15( 00044 q15_t * pSrc, 00045 uint32_t fftLen, 00046 q15_t * pCoef, 00047 uint32_t twidCoefModifier); 00048 00049 extern void arm_radix4_butterfly_inverse_q15( 00050 q15_t * pSrc, 00051 uint32_t fftLen, 00052 q15_t * pCoef, 00053 uint32_t twidCoefModifier); 00054 00055 extern void arm_bitreversal_16( 00056 uint16_t * pSrc, 00057 const uint16_t bitRevLen, 00058 const uint16_t * pBitRevTable); 00059 00060 void arm_cfft_radix4by2_q15( 00061 q15_t * pSrc, 00062 uint32_t fftLen, 00063 const q15_t * pCoef); 00064 00065 void arm_cfft_radix4by2_inverse_q15( 00066 q15_t * pSrc, 00067 uint32_t fftLen, 00068 const q15_t * pCoef); 00069 00070 /** 00071 * @ingroup groupTransforms 00072 */ 00073 00074 /** 00075 * @addtogroup ComplexFFT 00076 * @{ 00077 */ 00078 00079 /** 00080 * @details 00081 * @brief Processing function for the Q15 complex FFT. 00082 * @param[in] *S points to an instance of the Q15 CFFT structure. 00083 * @param[in, out] *p1 points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place. 00084 * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. 00085 * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. 00086 * @return none. 00087 */ 00088 00089 void arm_cfft_q15( 00090 const arm_cfft_instance_q15 * S, 00091 q15_t * p1, 00092 uint8_t ifftFlag, 00093 uint8_t bitReverseFlag) 00094 { 00095 uint32_t L = S->fftLen; 00096 00097 if(ifftFlag == 1u) 00098 { 00099 switch (L) 00100 { 00101 case 16: 00102 case 64: 00103 case 256: 00104 case 1024: 00105 case 4096: 00106 arm_radix4_butterfly_inverse_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 ); 00107 break; 00108 00109 case 32: 00110 case 128: 00111 case 512: 00112 case 2048: 00113 arm_cfft_radix4by2_inverse_q15 ( p1, L, S->pTwiddle ); 00114 break; 00115 } 00116 } 00117 else 00118 { 00119 switch (L) 00120 { 00121 case 16: 00122 case 64: 00123 case 256: 00124 case 1024: 00125 case 4096: 00126 arm_radix4_butterfly_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 ); 00127 break; 00128 00129 case 32: 00130 case 128: 00131 case 512: 00132 case 2048: 00133 arm_cfft_radix4by2_q15 ( p1, L, S->pTwiddle ); 00134 break; 00135 } 00136 } 00137 00138 if( bitReverseFlag ) 00139 arm_bitreversal_16((uint16_t*)p1,S->bitRevLength,S->pBitRevTable); 00140 } 00141 00142 /** 00143 * @} end of ComplexFFT group 00144 */ 00145 00146 void arm_cfft_radix4by2_q15( 00147 q15_t * pSrc, 00148 uint32_t fftLen, 00149 const q15_t * pCoef) 00150 { 00151 uint32_t i; 00152 uint32_t n2; 00153 q15_t p0, p1, p2, p3; 00154 #ifndef ARM_MATH_CM0_FAMILY 00155 q31_t T, S, R; 00156 q31_t coeff, out1, out2; 00157 const q15_t *pC = pCoef; 00158 q15_t *pSi = pSrc; 00159 q15_t *pSl = pSrc + fftLen; 00160 #else 00161 uint32_t ia, l; 00162 q15_t xt, yt, cosVal, sinVal; 00163 #endif 00164 00165 n2 = fftLen >> 1; 00166 00167 #ifndef ARM_MATH_CM0_FAMILY 00168 00169 for (i = n2; i > 0; i--) 00170 { 00171 coeff = _SIMD32_OFFSET(pC); 00172 pC += 2; 00173 00174 T = _SIMD32_OFFSET(pSi); 00175 T = __SHADD16(T, 0); // this is just a SIMD arithmetic shift right by 1 00176 00177 S = _SIMD32_OFFSET(pSl); 00178 S = __SHADD16(S, 0); // this is just a SIMD arithmetic shift right by 1 00179 00180 R = __QSUB16(T, S); 00181 00182 _SIMD32_OFFSET(pSi) = __SHADD16(T, S); 00183 pSi += 2; 00184 00185 #ifndef ARM_MATH_BIG_ENDIAN 00186 00187 out1 = __SMUAD(coeff, R) >> 16; 00188 out2 = __SMUSDX(coeff, R); 00189 00190 #else 00191 00192 out1 = __SMUSDX(R, coeff) >> 16u; 00193 out2 = __SMUAD(coeff, R); 00194 00195 #endif // #ifndef ARM_MATH_BIG_ENDIAN 00196 00197 _SIMD32_OFFSET(pSl) = 00198 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF); 00199 pSl += 2; 00200 } 00201 00202 #else // #ifndef ARM_MATH_CM0_FAMILY 00203 00204 ia = 0; 00205 for (i = 0; i < n2; i++) 00206 { 00207 cosVal = pCoef[ia * 2]; 00208 sinVal = pCoef[(ia * 2) + 1]; 00209 ia++; 00210 00211 l = i + n2; 00212 00213 xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u); 00214 pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u; 00215 00216 yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u); 00217 pSrc[2 * i + 1] = 00218 ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u; 00219 00220 pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) + 00221 ((int16_t) (((q31_t) yt * sinVal) >> 16))); 00222 00223 pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) - 00224 ((int16_t) (((q31_t) xt * sinVal) >> 16))); 00225 } 00226 00227 #endif // #ifndef ARM_MATH_CM0_FAMILY 00228 00229 // first col 00230 arm_radix4_butterfly_q15( pSrc, n2, (q15_t*)pCoef, 2u); 00231 // second col 00232 arm_radix4_butterfly_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2u); 00233 00234 for (i = 0; i < fftLen >> 1; i++) 00235 { 00236 p0 = pSrc[4*i+0]; 00237 p1 = pSrc[4*i+1]; 00238 p2 = pSrc[4*i+2]; 00239 p3 = pSrc[4*i+3]; 00240 00241 p0 <<= 1; 00242 p1 <<= 1; 00243 p2 <<= 1; 00244 p3 <<= 1; 00245 00246 pSrc[4*i+0] = p0; 00247 pSrc[4*i+1] = p1; 00248 pSrc[4*i+2] = p2; 00249 pSrc[4*i+3] = p3; 00250 } 00251 } 00252 00253 void arm_cfft_radix4by2_inverse_q15( 00254 q15_t * pSrc, 00255 uint32_t fftLen, 00256 const q15_t * pCoef) 00257 { 00258 uint32_t i; 00259 uint32_t n2; 00260 q15_t p0, p1, p2, p3; 00261 #ifndef ARM_MATH_CM0_FAMILY 00262 q31_t T, S, R; 00263 q31_t coeff, out1, out2; 00264 const q15_t *pC = pCoef; 00265 q15_t *pSi = pSrc; 00266 q15_t *pSl = pSrc + fftLen; 00267 #else 00268 uint32_t ia, l; 00269 q15_t xt, yt, cosVal, sinVal; 00270 #endif 00271 00272 n2 = fftLen >> 1; 00273 00274 #ifndef ARM_MATH_CM0_FAMILY 00275 00276 for (i = n2; i > 0; i--) 00277 { 00278 coeff = _SIMD32_OFFSET(pC); 00279 pC += 2; 00280 00281 T = _SIMD32_OFFSET(pSi); 00282 T = __SHADD16(T, 0); // this is just a SIMD arithmetic shift right by 1 00283 00284 S = _SIMD32_OFFSET(pSl); 00285 S = __SHADD16(S, 0); // this is just a SIMD arithmetic shift right by 1 00286 00287 R = __QSUB16(T, S); 00288 00289 _SIMD32_OFFSET(pSi) = __SHADD16(T, S); 00290 pSi += 2; 00291 00292 #ifndef ARM_MATH_BIG_ENDIAN 00293 00294 out1 = __SMUSD(coeff, R) >> 16; 00295 out2 = __SMUADX(coeff, R); 00296 #else 00297 00298 out1 = __SMUADX(R, coeff) >> 16u; 00299 out2 = __SMUSD(__QSUB(0, coeff), R); 00300 00301 #endif // #ifndef ARM_MATH_BIG_ENDIAN 00302 00303 _SIMD32_OFFSET(pSl) = 00304 (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF); 00305 pSl += 2; 00306 } 00307 00308 #else // #ifndef ARM_MATH_CM0_FAMILY 00309 00310 ia = 0; 00311 for (i = 0; i < n2; i++) 00312 { 00313 cosVal = pCoef[ia * 2]; 00314 sinVal = pCoef[(ia * 2) + 1]; 00315 ia++; 00316 00317 l = i + n2; 00318 xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u); 00319 pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u; 00320 00321 yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u); 00322 pSrc[2 * i + 1] = 00323 ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u; 00324 00325 pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) - 00326 ((int16_t) (((q31_t) yt * sinVal) >> 16))); 00327 00328 pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) + 00329 ((int16_t) (((q31_t) xt * sinVal) >> 16))); 00330 } 00331 00332 #endif // #ifndef ARM_MATH_CM0_FAMILY 00333 00334 // first col 00335 arm_radix4_butterfly_inverse_q15( pSrc, n2, (q15_t*)pCoef, 2u); 00336 // second col 00337 arm_radix4_butterfly_inverse_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2u); 00338 00339 for (i = 0; i < fftLen >> 1; i++) 00340 { 00341 p0 = pSrc[4*i+0]; 00342 p1 = pSrc[4*i+1]; 00343 p2 = pSrc[4*i+2]; 00344 p3 = pSrc[4*i+3]; 00345 00346 p0 <<= 1; 00347 p1 <<= 1; 00348 p2 <<= 1; 00349 p3 <<= 1; 00350 00351 pSrc[4*i+0] = p0; 00352 pSrc[4*i+1] = p1; 00353 pSrc[4*i+2] = p2; 00354 pSrc[4*i+3] = p3; 00355 } 00356 } 00357
Generated on Tue Jul 12 2022 13:15:19 by
