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_rfft_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_rfft_q31.c 00009 * 00010 * Description: RFFT & RIFFT Q31 process function 00011 * 00012 * 00013 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 00014 * 00015 * Redistribution and use in source and binary forms, with or without 00016 * modification, are permitted provided that the following conditions 00017 * are met: 00018 * - Redistributions of source code must retain the above copyright 00019 * notice, this list of conditions and the following disclaimer. 00020 * - Redistributions in binary form must reproduce the above copyright 00021 * notice, this list of conditions and the following disclaimer in 00022 * the documentation and/or other materials provided with the 00023 * distribution. 00024 * - Neither the name of ARM LIMITED nor the names of its contributors 00025 * may be used to endorse or promote products derived from this 00026 * software without specific prior written permission. 00027 * 00028 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00029 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00030 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00031 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00032 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00033 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00034 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00035 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00036 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00037 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00038 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00039 * POSSIBILITY OF SUCH DAMAGE. 00040 * -------------------------------------------------------------------- */ 00041 00042 #include "arm_math.h" 00043 00044 /*-------------------------------------------------------------------- 00045 * Internal functions prototypes 00046 --------------------------------------------------------------------*/ 00047 00048 void arm_split_rfft_q31( 00049 q31_t * pSrc, 00050 uint32_t fftLen, 00051 q31_t * pATable, 00052 q31_t * pBTable, 00053 q31_t * pDst, 00054 uint32_t modifier); 00055 00056 void arm_split_rifft_q31( 00057 q31_t * pSrc, 00058 uint32_t fftLen, 00059 q31_t * pATable, 00060 q31_t * pBTable, 00061 q31_t * pDst, 00062 uint32_t modifier); 00063 00064 /** 00065 * @addtogroup RealFFT 00066 * @{ 00067 */ 00068 00069 /** 00070 * @brief Processing function for the Q31 RFFT/RIFFT. 00071 * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure. 00072 * @param[in] *pSrc points to the input buffer. 00073 * @param[out] *pDst points to the output buffer. 00074 * @return none. 00075 * 00076 * \par Input an output formats: 00077 * \par 00078 * Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process. 00079 * Hence the output format is different for different RFFT sizes. 00080 * The input and output formats for different RFFT sizes and number of bits to upscale are mentioned in the tables below for RFFT and RIFFT: 00081 * \par 00082 * \image html RFFTQ31.gif "Input and Output Formats for Q31 RFFT" 00083 * 00084 * \par 00085 * \image html RIFFTQ31.gif "Input and Output Formats for Q31 RIFFT" 00086 */ 00087 void arm_rfft_q31( 00088 const arm_rfft_instance_q31 * S, 00089 q31_t * pSrc, 00090 q31_t * pDst) 00091 { 00092 const arm_cfft_instance_q31 *S_CFFT = S->pCfft; 00093 uint32_t i; 00094 uint32_t L2 = S->fftLenReal >> 1; 00095 00096 /* Calculation of RIFFT of input */ 00097 if(S->ifftFlagR == 1u) 00098 { 00099 /* Real IFFT core process */ 00100 arm_split_rifft_q31(pSrc, L2, S->pTwiddleAReal, 00101 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00102 00103 /* Complex IFFT process */ 00104 arm_cfft_q31(S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR); 00105 00106 for(i=0;i<S->fftLenReal;i++) 00107 { 00108 pDst[i] = pDst[i] << 1; 00109 } 00110 } 00111 else 00112 { 00113 /* Calculation of RFFT of input */ 00114 00115 /* Complex FFT process */ 00116 arm_cfft_q31(S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR); 00117 00118 /* Real FFT core process */ 00119 arm_split_rfft_q31(pSrc, L2, S->pTwiddleAReal, 00120 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00121 } 00122 } 00123 00124 /** 00125 * @} end of RealFFT group 00126 */ 00127 00128 /** 00129 * @brief Core Real FFT process 00130 * @param[in] *pSrc points to the input buffer. 00131 * @param[in] fftLen length of FFT. 00132 * @param[in] *pATable points to the twiddle Coef A buffer. 00133 * @param[in] *pBTable points to the twiddle Coef B buffer. 00134 * @param[out] *pDst points to the output buffer. 00135 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00136 * @return none. 00137 */ 00138 void arm_split_rfft_q31( 00139 q31_t * pSrc, 00140 uint32_t fftLen, 00141 q31_t * pATable, 00142 q31_t * pBTable, 00143 q31_t * pDst, 00144 uint32_t modifier) 00145 { 00146 uint32_t i; /* Loop Counter */ 00147 q31_t outR, outI; /* Temporary variables for output */ 00148 q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00149 q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ 00150 q31_t *pOut1 = &pDst[2], *pOut2 = &pDst[(4u * fftLen) - 1u]; 00151 q31_t *pIn1 = &pSrc[2], *pIn2 = &pSrc[(2u * fftLen) - 1u]; 00152 00153 /* Init coefficient pointers */ 00154 pCoefA = &pATable[modifier * 2u]; 00155 pCoefB = &pBTable[modifier * 2u]; 00156 00157 i = fftLen - 1u; 00158 00159 while(i > 0u) 00160 { 00161 /* 00162 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] 00163 + pSrc[2 * n - 2 * i] * pBTable[2 * i] + 00164 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00165 */ 00166 00167 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] + 00168 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00169 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */ 00170 00171 CoefA1 = *pCoefA++; 00172 CoefA2 = *pCoefA; 00173 00174 /* outR = (pSrc[2 * i] * pATable[2 * i] */ 00175 mult_32x32_keep32_R(outR, *pIn1, CoefA1); 00176 00177 /* outI = pIn[2 * i] * pATable[2 * i + 1] */ 00178 mult_32x32_keep32_R(outI, *pIn1++, CoefA2); 00179 00180 /* - pSrc[2 * i + 1] * pATable[2 * i + 1] */ 00181 multSub_32x32_keep32_R(outR, *pIn1, CoefA2); 00182 00183 /* (pIn[2 * i + 1] * pATable[2 * i] */ 00184 multAcc_32x32_keep32_R(outI, *pIn1++, CoefA1); 00185 00186 /* pSrc[2 * n - 2 * i] * pBTable[2 * i] */ 00187 multSub_32x32_keep32_R(outR, *pIn2, CoefA2); 00188 CoefB1 = *pCoefB; 00189 00190 /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */ 00191 multSub_32x32_keep32_R(outI, *pIn2--, CoefB1); 00192 00193 /* pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */ 00194 multAcc_32x32_keep32_R(outR, *pIn2, CoefB1); 00195 00196 /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ 00197 multSub_32x32_keep32_R(outI, *pIn2--, CoefA2); 00198 00199 /* write output */ 00200 *pOut1++ = outR; 00201 *pOut1++ = outI; 00202 00203 /* write complex conjugate output */ 00204 *pOut2-- = -outI; 00205 *pOut2-- = outR; 00206 00207 /* update coefficient pointer */ 00208 pCoefB = pCoefB + (modifier * 2u); 00209 pCoefA = pCoefA + ((modifier * 2u) - 1u); 00210 00211 i--; 00212 } 00213 pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1; 00214 pDst[(2u * fftLen) + 1u] = 0; 00215 00216 pDst[0] = (pSrc[0] + pSrc[1]) >> 1; 00217 pDst[1] = 0; 00218 } 00219 00220 /** 00221 * @brief Core Real IFFT process 00222 * @param[in] *pSrc points to the input buffer. 00223 * @param[in] fftLen length of FFT. 00224 * @param[in] *pATable points to the twiddle Coef A buffer. 00225 * @param[in] *pBTable points to the twiddle Coef B buffer. 00226 * @param[out] *pDst points to the output buffer. 00227 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00228 * @return none. 00229 */ 00230 void arm_split_rifft_q31( 00231 q31_t * pSrc, 00232 uint32_t fftLen, 00233 q31_t * pATable, 00234 q31_t * pBTable, 00235 q31_t * pDst, 00236 uint32_t modifier) 00237 { 00238 q31_t outR, outI; /* Temporary variables for output */ 00239 q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00240 q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ 00241 q31_t *pIn1 = &pSrc[0], *pIn2 = &pSrc[(2u * fftLen) + 1u]; 00242 00243 pCoefA = &pATable[0]; 00244 pCoefB = &pBTable[0]; 00245 00246 while(fftLen > 0u) 00247 { 00248 /* 00249 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] + 00250 pIn[2 * n - 2 * i] * pBTable[2 * i] - 00251 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00252 00253 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] - 00254 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00255 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); 00256 */ 00257 CoefA1 = *pCoefA++; 00258 CoefA2 = *pCoefA; 00259 00260 /* outR = (pIn[2 * i] * pATable[2 * i] */ 00261 mult_32x32_keep32_R(outR, *pIn1, CoefA1); 00262 00263 /* - pIn[2 * i] * pATable[2 * i + 1] */ 00264 mult_32x32_keep32_R(outI, *pIn1++, -CoefA2); 00265 00266 /* pIn[2 * i + 1] * pATable[2 * i + 1] */ 00267 multAcc_32x32_keep32_R(outR, *pIn1, CoefA2); 00268 00269 /* pIn[2 * i + 1] * pATable[2 * i] */ 00270 multAcc_32x32_keep32_R(outI, *pIn1++, CoefA1); 00271 00272 /* pIn[2 * n - 2 * i] * pBTable[2 * i] */ 00273 multAcc_32x32_keep32_R(outR, *pIn2, CoefA2); 00274 CoefB1 = *pCoefB; 00275 00276 /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */ 00277 multSub_32x32_keep32_R(outI, *pIn2--, CoefB1); 00278 00279 /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */ 00280 multAcc_32x32_keep32_R(outR, *pIn2, CoefB1); 00281 00282 /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ 00283 multAcc_32x32_keep32_R(outI, *pIn2--, CoefA2); 00284 00285 /* write output */ 00286 *pDst++ = outR; 00287 *pDst++ = outI; 00288 00289 /* update coefficient pointer */ 00290 pCoefB = pCoefB + (modifier * 2u); 00291 pCoefA = pCoefA + ((modifier * 2u) - 1u); 00292 00293 /* Decrement loop count */ 00294 fftLen--; 00295 } 00296 }
Generated on Tue Jul 12 2022 13:15:28 by
