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_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 13:15:19 by
