CMSIS DSP library
Dependents: performance_timer Surfboard_ gps2rtty Capstone ... more
arm_cfft_q31.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_q31.c 00009 * 00010 * Description: Combined Radix Decimation in Frequency CFFT fixed 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 extern void arm_radix4_butterfly_q31( 00044 q31_t * pSrc, 00045 uint32_t fftLen, 00046 q31_t * pCoef, 00047 uint32_t twidCoefModifier); 00048 00049 extern void arm_radix4_butterfly_inverse_q31( 00050 q31_t * pSrc, 00051 uint32_t fftLen, 00052 q31_t * pCoef, 00053 uint32_t twidCoefModifier); 00054 00055 extern void arm_bitreversal_32( 00056 uint32_t * pSrc, 00057 const uint16_t bitRevLen, 00058 const uint16_t * pBitRevTable); 00059 00060 void arm_cfft_radix4by2_q31( 00061 q31_t * pSrc, 00062 uint32_t fftLen, 00063 const q31_t * pCoef); 00064 00065 void arm_cfft_radix4by2_inverse_q31( 00066 q31_t * pSrc, 00067 uint32_t fftLen, 00068 const q31_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 fixed-point complex FFT in Q31 format. 00082 * @param[in] *S points to an instance of the fixed-point 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_q31( 00090 const arm_cfft_instance_q31 * S, 00091 q31_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_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 ); 00107 break; 00108 00109 case 32: 00110 case 128: 00111 case 512: 00112 case 2048: 00113 arm_cfft_radix4by2_inverse_q31 ( 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_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 ); 00127 break; 00128 00129 case 32: 00130 case 128: 00131 case 512: 00132 case 2048: 00133 arm_cfft_radix4by2_q31 ( p1, L, S->pTwiddle ); 00134 break; 00135 } 00136 } 00137 00138 if( bitReverseFlag ) 00139 arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable); 00140 } 00141 00142 /** 00143 * @} end of ComplexFFT group 00144 */ 00145 00146 void arm_cfft_radix4by2_q31( 00147 q31_t * pSrc, 00148 uint32_t fftLen, 00149 const q31_t * pCoef) 00150 { 00151 uint32_t i, l; 00152 uint32_t n2, ia; 00153 q31_t xt, yt, cosVal, sinVal; 00154 q31_t p0, p1; 00155 00156 n2 = fftLen >> 1; 00157 ia = 0; 00158 for (i = 0; i < n2; i++) 00159 { 00160 cosVal = pCoef[2*ia]; 00161 sinVal = pCoef[2*ia + 1]; 00162 ia++; 00163 00164 l = i + n2; 00165 xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2); 00166 pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2); 00167 00168 yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2); 00169 pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2); 00170 00171 mult_32x32_keep32_R(p0, xt, cosVal); 00172 mult_32x32_keep32_R(p1, yt, cosVal); 00173 multAcc_32x32_keep32_R(p0, yt, sinVal); 00174 multSub_32x32_keep32_R(p1, xt, sinVal); 00175 00176 pSrc[2u * l] = p0 << 1; 00177 pSrc[2u * l + 1u] = p1 << 1; 00178 00179 } 00180 00181 // first col 00182 arm_radix4_butterfly_q31( pSrc, n2, (q31_t*)pCoef, 2u); 00183 // second col 00184 arm_radix4_butterfly_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2u); 00185 00186 for (i = 0; i < fftLen >> 1; i++) 00187 { 00188 p0 = pSrc[4*i+0]; 00189 p1 = pSrc[4*i+1]; 00190 xt = pSrc[4*i+2]; 00191 yt = pSrc[4*i+3]; 00192 00193 p0 <<= 1; 00194 p1 <<= 1; 00195 xt <<= 1; 00196 yt <<= 1; 00197 00198 pSrc[4*i+0] = p0; 00199 pSrc[4*i+1] = p1; 00200 pSrc[4*i+2] = xt; 00201 pSrc[4*i+3] = yt; 00202 } 00203 00204 } 00205 00206 void arm_cfft_radix4by2_inverse_q31( 00207 q31_t * pSrc, 00208 uint32_t fftLen, 00209 const q31_t * pCoef) 00210 { 00211 uint32_t i, l; 00212 uint32_t n2, ia; 00213 q31_t xt, yt, cosVal, sinVal; 00214 q31_t p0, p1; 00215 00216 n2 = fftLen >> 1; 00217 ia = 0; 00218 for (i = 0; i < n2; i++) 00219 { 00220 cosVal = pCoef[2*ia]; 00221 sinVal = pCoef[2*ia + 1]; 00222 ia++; 00223 00224 l = i + n2; 00225 xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2); 00226 pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2); 00227 00228 yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2); 00229 pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2); 00230 00231 mult_32x32_keep32_R(p0, xt, cosVal); 00232 mult_32x32_keep32_R(p1, yt, cosVal); 00233 multSub_32x32_keep32_R(p0, yt, sinVal); 00234 multAcc_32x32_keep32_R(p1, xt, sinVal); 00235 00236 pSrc[2u * l] = p0 << 1; 00237 pSrc[2u * l + 1u] = p1 << 1; 00238 00239 } 00240 00241 // first col 00242 arm_radix4_butterfly_inverse_q31( pSrc, n2, (q31_t*)pCoef, 2u); 00243 // second col 00244 arm_radix4_butterfly_inverse_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2u); 00245 00246 for (i = 0; i < fftLen >> 1; i++) 00247 { 00248 p0 = pSrc[4*i+0]; 00249 p1 = pSrc[4*i+1]; 00250 xt = pSrc[4*i+2]; 00251 yt = pSrc[4*i+3]; 00252 00253 p0 <<= 1; 00254 p1 <<= 1; 00255 xt <<= 1; 00256 yt <<= 1; 00257 00258 pSrc[4*i+0] = p0; 00259 pSrc[4*i+1] = p1; 00260 pSrc[4*i+2] = xt; 00261 pSrc[4*i+3] = yt; 00262 } 00263 } 00264
Generated on Tue Jul 12 2022 11:59:15 by 1.7.2