CMSIS DSP Lib

Fork of mbed-dsp by mbed official

Committer:
emilmont
Date:
Wed Nov 28 12:30:09 2012 +0000
Revision:
1:fdd22bb7aa52
Child:
2:da51fb522205
DSP library code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 1:fdd22bb7aa52 1 /* ----------------------------------------------------------------------
emilmont 1:fdd22bb7aa52 2 * Copyright (C) 2010 ARM Limited. All rights reserved.
emilmont 1:fdd22bb7aa52 3 *
emilmont 1:fdd22bb7aa52 4 * $Date: 15. February 2012
emilmont 1:fdd22bb7aa52 5 * $Revision: V1.1.0
emilmont 1:fdd22bb7aa52 6 *
emilmont 1:fdd22bb7aa52 7 * Project: CMSIS DSP Library
emilmont 1:fdd22bb7aa52 8 * Title: arm_rfft_q15.c
emilmont 1:fdd22bb7aa52 9 *
emilmont 1:fdd22bb7aa52 10 * Description: RFFT & RIFFT Q15 process function
emilmont 1:fdd22bb7aa52 11 *
emilmont 1:fdd22bb7aa52 12 *
emilmont 1:fdd22bb7aa52 13 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
emilmont 1:fdd22bb7aa52 14 *
emilmont 1:fdd22bb7aa52 15 * Version 1.1.0 2012/02/15
emilmont 1:fdd22bb7aa52 16 * Updated with more optimizations, bug fixes and minor API changes.
emilmont 1:fdd22bb7aa52 17 *
emilmont 1:fdd22bb7aa52 18 * Version 1.0.10 2011/7/15
emilmont 1:fdd22bb7aa52 19 * Big Endian support added and Merged M0 and M3/M4 Source code.
emilmont 1:fdd22bb7aa52 20 *
emilmont 1:fdd22bb7aa52 21 * Version 1.0.3 2010/11/29
emilmont 1:fdd22bb7aa52 22 * Re-organized the CMSIS folders and updated documentation.
emilmont 1:fdd22bb7aa52 23 *
emilmont 1:fdd22bb7aa52 24 * Version 1.0.2 2010/11/11
emilmont 1:fdd22bb7aa52 25 * Documentation updated.
emilmont 1:fdd22bb7aa52 26 *
emilmont 1:fdd22bb7aa52 27 * Version 1.0.1 2010/10/05
emilmont 1:fdd22bb7aa52 28 * Production release and review comments incorporated.
emilmont 1:fdd22bb7aa52 29 *
emilmont 1:fdd22bb7aa52 30 * Version 1.0.0 2010/09/20
emilmont 1:fdd22bb7aa52 31 * Production release and review comments incorporated
emilmont 1:fdd22bb7aa52 32 *
emilmont 1:fdd22bb7aa52 33 * Version 0.0.7 2010/06/10
emilmont 1:fdd22bb7aa52 34 * Misra-C changes done
emilmont 1:fdd22bb7aa52 35 * -------------------------------------------------------------------- */
emilmont 1:fdd22bb7aa52 36
emilmont 1:fdd22bb7aa52 37
emilmont 1:fdd22bb7aa52 38 #include "arm_math.h"
emilmont 1:fdd22bb7aa52 39
emilmont 1:fdd22bb7aa52 40 /*--------------------------------------------------------------------
emilmont 1:fdd22bb7aa52 41 * Internal functions prototypes
emilmont 1:fdd22bb7aa52 42 --------------------------------------------------------------------*/
emilmont 1:fdd22bb7aa52 43
emilmont 1:fdd22bb7aa52 44 void arm_split_rfft_q15(
emilmont 1:fdd22bb7aa52 45 q15_t * pSrc,
emilmont 1:fdd22bb7aa52 46 uint32_t fftLen,
emilmont 1:fdd22bb7aa52 47 q15_t * pATable,
emilmont 1:fdd22bb7aa52 48 q15_t * pBTable,
emilmont 1:fdd22bb7aa52 49 q15_t * pDst,
emilmont 1:fdd22bb7aa52 50 uint32_t modifier);
emilmont 1:fdd22bb7aa52 51
emilmont 1:fdd22bb7aa52 52 void arm_split_rifft_q15(
emilmont 1:fdd22bb7aa52 53 q15_t * pSrc,
emilmont 1:fdd22bb7aa52 54 uint32_t fftLen,
emilmont 1:fdd22bb7aa52 55 q15_t * pATable,
emilmont 1:fdd22bb7aa52 56 q15_t * pBTable,
emilmont 1:fdd22bb7aa52 57 q15_t * pDst,
emilmont 1:fdd22bb7aa52 58 uint32_t modifier);
emilmont 1:fdd22bb7aa52 59
emilmont 1:fdd22bb7aa52 60 /**
emilmont 1:fdd22bb7aa52 61 * @addtogroup RFFT_RIFFT
emilmont 1:fdd22bb7aa52 62 * @{
emilmont 1:fdd22bb7aa52 63 */
emilmont 1:fdd22bb7aa52 64
emilmont 1:fdd22bb7aa52 65 /**
emilmont 1:fdd22bb7aa52 66 * @brief Processing function for the Q15 RFFT/RIFFT.
emilmont 1:fdd22bb7aa52 67 * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure.
emilmont 1:fdd22bb7aa52 68 * @param[in] *pSrc points to the input buffer.
emilmont 1:fdd22bb7aa52 69 * @param[out] *pDst points to the output buffer.
emilmont 1:fdd22bb7aa52 70 * @return none.
emilmont 1:fdd22bb7aa52 71 *
emilmont 1:fdd22bb7aa52 72 * \par Input an output formats:
emilmont 1:fdd22bb7aa52 73 * \par
emilmont 1:fdd22bb7aa52 74 * Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process.
emilmont 1:fdd22bb7aa52 75 * Hence the output format is different for different RFFT sizes.
emilmont 1:fdd22bb7aa52 76 * 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:
emilmont 1:fdd22bb7aa52 77 * \par
emilmont 1:fdd22bb7aa52 78 * \image html RFFTQ15.gif "Input and Output Formats for Q15 RFFT"
emilmont 1:fdd22bb7aa52 79 * \par
emilmont 1:fdd22bb7aa52 80 * \image html RIFFTQ15.gif "Input and Output Formats for Q15 RIFFT"
emilmont 1:fdd22bb7aa52 81 */
emilmont 1:fdd22bb7aa52 82
emilmont 1:fdd22bb7aa52 83 void arm_rfft_q15(
emilmont 1:fdd22bb7aa52 84 const arm_rfft_instance_q15 * S,
emilmont 1:fdd22bb7aa52 85 q15_t * pSrc,
emilmont 1:fdd22bb7aa52 86 q15_t * pDst)
emilmont 1:fdd22bb7aa52 87 {
emilmont 1:fdd22bb7aa52 88 const arm_cfft_radix4_instance_q15 *S_CFFT = S->pCfft;
emilmont 1:fdd22bb7aa52 89
emilmont 1:fdd22bb7aa52 90 /* Calculation of RIFFT of input */
emilmont 1:fdd22bb7aa52 91 if(S->ifftFlagR == 1u)
emilmont 1:fdd22bb7aa52 92 {
emilmont 1:fdd22bb7aa52 93 /* Real IFFT core process */
emilmont 1:fdd22bb7aa52 94 arm_split_rifft_q15(pSrc, S->fftLenBy2, S->pTwiddleAReal,
emilmont 1:fdd22bb7aa52 95 S->pTwiddleBReal, pDst, S->twidCoefRModifier);
emilmont 1:fdd22bb7aa52 96
emilmont 1:fdd22bb7aa52 97 /* Complex readix-4 IFFT process */
emilmont 1:fdd22bb7aa52 98 arm_radix4_butterfly_inverse_q15(pDst, S_CFFT->fftLen,
emilmont 1:fdd22bb7aa52 99 S_CFFT->pTwiddle,
emilmont 1:fdd22bb7aa52 100 S_CFFT->twidCoefModifier);
emilmont 1:fdd22bb7aa52 101
emilmont 1:fdd22bb7aa52 102 /* Bit reversal process */
emilmont 1:fdd22bb7aa52 103 if(S->bitReverseFlagR == 1u)
emilmont 1:fdd22bb7aa52 104 {
emilmont 1:fdd22bb7aa52 105 arm_bitreversal_q15(pDst, S_CFFT->fftLen,
emilmont 1:fdd22bb7aa52 106 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
emilmont 1:fdd22bb7aa52 107 }
emilmont 1:fdd22bb7aa52 108 }
emilmont 1:fdd22bb7aa52 109 else
emilmont 1:fdd22bb7aa52 110 {
emilmont 1:fdd22bb7aa52 111 /* Calculation of RFFT of input */
emilmont 1:fdd22bb7aa52 112
emilmont 1:fdd22bb7aa52 113 /* Complex readix-4 FFT process */
emilmont 1:fdd22bb7aa52 114 arm_radix4_butterfly_q15(pSrc, S_CFFT->fftLen,
emilmont 1:fdd22bb7aa52 115 S_CFFT->pTwiddle, S_CFFT->twidCoefModifier);
emilmont 1:fdd22bb7aa52 116
emilmont 1:fdd22bb7aa52 117 /* Bit reversal process */
emilmont 1:fdd22bb7aa52 118 if(S->bitReverseFlagR == 1u)
emilmont 1:fdd22bb7aa52 119 {
emilmont 1:fdd22bb7aa52 120 arm_bitreversal_q15(pSrc, S_CFFT->fftLen,
emilmont 1:fdd22bb7aa52 121 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
emilmont 1:fdd22bb7aa52 122 }
emilmont 1:fdd22bb7aa52 123
emilmont 1:fdd22bb7aa52 124 arm_split_rfft_q15(pSrc, S->fftLenBy2, S->pTwiddleAReal,
emilmont 1:fdd22bb7aa52 125 S->pTwiddleBReal, pDst, S->twidCoefRModifier);
emilmont 1:fdd22bb7aa52 126 }
emilmont 1:fdd22bb7aa52 127
emilmont 1:fdd22bb7aa52 128 }
emilmont 1:fdd22bb7aa52 129
emilmont 1:fdd22bb7aa52 130 /**
emilmont 1:fdd22bb7aa52 131 * @} end of RFFT_RIFFT group
emilmont 1:fdd22bb7aa52 132 */
emilmont 1:fdd22bb7aa52 133
emilmont 1:fdd22bb7aa52 134 /**
emilmont 1:fdd22bb7aa52 135 * @brief Core Real FFT process
emilmont 1:fdd22bb7aa52 136 * @param *pSrc points to the input buffer.
emilmont 1:fdd22bb7aa52 137 * @param fftLen length of FFT.
emilmont 1:fdd22bb7aa52 138 * @param *pATable points to the A twiddle Coef buffer.
emilmont 1:fdd22bb7aa52 139 * @param *pBTable points to the B twiddle Coef buffer.
emilmont 1:fdd22bb7aa52 140 * @param *pDst points to the output buffer.
emilmont 1:fdd22bb7aa52 141 * @param modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
emilmont 1:fdd22bb7aa52 142 * @return none.
emilmont 1:fdd22bb7aa52 143 * The function implements a Real FFT
emilmont 1:fdd22bb7aa52 144 */
emilmont 1:fdd22bb7aa52 145
emilmont 1:fdd22bb7aa52 146 void arm_split_rfft_q15(
emilmont 1:fdd22bb7aa52 147 q15_t * pSrc,
emilmont 1:fdd22bb7aa52 148 uint32_t fftLen,
emilmont 1:fdd22bb7aa52 149 q15_t * pATable,
emilmont 1:fdd22bb7aa52 150 q15_t * pBTable,
emilmont 1:fdd22bb7aa52 151 q15_t * pDst,
emilmont 1:fdd22bb7aa52 152 uint32_t modifier)
emilmont 1:fdd22bb7aa52 153 {
emilmont 1:fdd22bb7aa52 154 uint32_t i; /* Loop Counter */
emilmont 1:fdd22bb7aa52 155 q31_t outR, outI; /* Temporary variables for output */
emilmont 1:fdd22bb7aa52 156 q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
emilmont 1:fdd22bb7aa52 157 q15_t *pSrc1, *pSrc2;
emilmont 1:fdd22bb7aa52 158
emilmont 1:fdd22bb7aa52 159
emilmont 1:fdd22bb7aa52 160 // pSrc[2u * fftLen] = pSrc[0];
emilmont 1:fdd22bb7aa52 161 // pSrc[(2u * fftLen) + 1u] = pSrc[1];
emilmont 1:fdd22bb7aa52 162
emilmont 1:fdd22bb7aa52 163 pCoefA = &pATable[modifier * 2u];
emilmont 1:fdd22bb7aa52 164 pCoefB = &pBTable[modifier * 2u];
emilmont 1:fdd22bb7aa52 165
emilmont 1:fdd22bb7aa52 166 pSrc1 = &pSrc[2];
emilmont 1:fdd22bb7aa52 167 pSrc2 = &pSrc[(2u * fftLen) - 2u];
emilmont 1:fdd22bb7aa52 168
emilmont 1:fdd22bb7aa52 169 #ifndef ARM_MATH_CM0
emilmont 1:fdd22bb7aa52 170
emilmont 1:fdd22bb7aa52 171 /* Run the below code for Cortex-M4 and Cortex-M3 */
emilmont 1:fdd22bb7aa52 172
emilmont 1:fdd22bb7aa52 173 i = 1u;
emilmont 1:fdd22bb7aa52 174
emilmont 1:fdd22bb7aa52 175 while(i < fftLen)
emilmont 1:fdd22bb7aa52 176 {
emilmont 1:fdd22bb7aa52 177 /*
emilmont 1:fdd22bb7aa52 178 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
emilmont 1:fdd22bb7aa52 179 + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
emilmont 1:fdd22bb7aa52 180 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
emilmont 1:fdd22bb7aa52 181 */
emilmont 1:fdd22bb7aa52 182
emilmont 1:fdd22bb7aa52 183 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
emilmont 1:fdd22bb7aa52 184 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
emilmont 1:fdd22bb7aa52 185 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
emilmont 1:fdd22bb7aa52 186
emilmont 1:fdd22bb7aa52 187
emilmont 1:fdd22bb7aa52 188 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 189
emilmont 1:fdd22bb7aa52 190 /* pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] */
emilmont 1:fdd22bb7aa52 191 outR = __SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA));
emilmont 1:fdd22bb7aa52 192
emilmont 1:fdd22bb7aa52 193 #else
emilmont 1:fdd22bb7aa52 194
emilmont 1:fdd22bb7aa52 195 /* -(pSrc[2 * i + 1] * pATable[2 * i + 1] - pSrc[2 * i] * pATable[2 * i]) */
emilmont 1:fdd22bb7aa52 196 outR = -(__SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA)));
emilmont 1:fdd22bb7aa52 197
emilmont 1:fdd22bb7aa52 198 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 199
emilmont 1:fdd22bb7aa52 200 /* pSrc[2 * n - 2 * i] * pBTable[2 * i] +
emilmont 1:fdd22bb7aa52 201 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
emilmont 1:fdd22bb7aa52 202 outR = __SMLAD(*__SIMD32(pSrc2), *__SIMD32(pCoefB), outR) >> 15u;
emilmont 1:fdd22bb7aa52 203
emilmont 1:fdd22bb7aa52 204 /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
emilmont 1:fdd22bb7aa52 205 pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
emilmont 1:fdd22bb7aa52 206
emilmont 1:fdd22bb7aa52 207 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 208
emilmont 1:fdd22bb7aa52 209 outI = __SMUSDX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
emilmont 1:fdd22bb7aa52 210
emilmont 1:fdd22bb7aa52 211 #else
emilmont 1:fdd22bb7aa52 212
emilmont 1:fdd22bb7aa52 213 outI = __SMUSDX(*__SIMD32(pCoefB), *__SIMD32(pSrc2)--);
emilmont 1:fdd22bb7aa52 214
emilmont 1:fdd22bb7aa52 215 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 216
emilmont 1:fdd22bb7aa52 217 /* (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] */
emilmont 1:fdd22bb7aa52 218 outI = __SMLADX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), outI);
emilmont 1:fdd22bb7aa52 219
emilmont 1:fdd22bb7aa52 220 /* write output */
emilmont 1:fdd22bb7aa52 221 pDst[2u * i] = (q15_t) outR;
emilmont 1:fdd22bb7aa52 222 pDst[(2u * i) + 1u] = outI >> 15u;
emilmont 1:fdd22bb7aa52 223
emilmont 1:fdd22bb7aa52 224 /* write complex conjugate output */
emilmont 1:fdd22bb7aa52 225 pDst[(4u * fftLen) - (2u * i)] = (q15_t) outR;
emilmont 1:fdd22bb7aa52 226 pDst[((4u * fftLen) - (2u * i)) + 1u] = -(outI >> 15u);
emilmont 1:fdd22bb7aa52 227
emilmont 1:fdd22bb7aa52 228 /* update coefficient pointer */
emilmont 1:fdd22bb7aa52 229 pCoefB = pCoefB + (2u * modifier);
emilmont 1:fdd22bb7aa52 230 pCoefA = pCoefA + (2u * modifier);
emilmont 1:fdd22bb7aa52 231
emilmont 1:fdd22bb7aa52 232 i++;
emilmont 1:fdd22bb7aa52 233
emilmont 1:fdd22bb7aa52 234 }
emilmont 1:fdd22bb7aa52 235
emilmont 1:fdd22bb7aa52 236 pDst[2u * fftLen] = pSrc[0] - pSrc[1];
emilmont 1:fdd22bb7aa52 237 pDst[(2u * fftLen) + 1u] = 0;
emilmont 1:fdd22bb7aa52 238
emilmont 1:fdd22bb7aa52 239 pDst[0] = pSrc[0] + pSrc[1];
emilmont 1:fdd22bb7aa52 240 pDst[1] = 0;
emilmont 1:fdd22bb7aa52 241
emilmont 1:fdd22bb7aa52 242
emilmont 1:fdd22bb7aa52 243 #else
emilmont 1:fdd22bb7aa52 244
emilmont 1:fdd22bb7aa52 245 /* Run the below code for Cortex-M0 */
emilmont 1:fdd22bb7aa52 246
emilmont 1:fdd22bb7aa52 247 i = 1u;
emilmont 1:fdd22bb7aa52 248
emilmont 1:fdd22bb7aa52 249 while(i < fftLen)
emilmont 1:fdd22bb7aa52 250 {
emilmont 1:fdd22bb7aa52 251 /*
emilmont 1:fdd22bb7aa52 252 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
emilmont 1:fdd22bb7aa52 253 + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
emilmont 1:fdd22bb7aa52 254 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
emilmont 1:fdd22bb7aa52 255 */
emilmont 1:fdd22bb7aa52 256
emilmont 1:fdd22bb7aa52 257 outR = *pSrc1 * *pCoefA;
emilmont 1:fdd22bb7aa52 258 outR = outR - (*(pSrc1 + 1) * *(pCoefA + 1));
emilmont 1:fdd22bb7aa52 259 outR = outR + (*pSrc2 * *pCoefB);
emilmont 1:fdd22bb7aa52 260 outR = (outR + (*(pSrc2 + 1) * *(pCoefB + 1))) >> 15;
emilmont 1:fdd22bb7aa52 261
emilmont 1:fdd22bb7aa52 262
emilmont 1:fdd22bb7aa52 263 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
emilmont 1:fdd22bb7aa52 264 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
emilmont 1:fdd22bb7aa52 265 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
emilmont 1:fdd22bb7aa52 266 */
emilmont 1:fdd22bb7aa52 267
emilmont 1:fdd22bb7aa52 268 outI = *pSrc2 * *(pCoefB + 1);
emilmont 1:fdd22bb7aa52 269 outI = outI - (*(pSrc2 + 1) * *pCoefB);
emilmont 1:fdd22bb7aa52 270 outI = outI + (*(pSrc1 + 1) * *pCoefA);
emilmont 1:fdd22bb7aa52 271 outI = outI + (*pSrc1 * *(pCoefA + 1));
emilmont 1:fdd22bb7aa52 272
emilmont 1:fdd22bb7aa52 273 /* update input pointers */
emilmont 1:fdd22bb7aa52 274 pSrc1 += 2u;
emilmont 1:fdd22bb7aa52 275 pSrc2 -= 2u;
emilmont 1:fdd22bb7aa52 276
emilmont 1:fdd22bb7aa52 277 /* write output */
emilmont 1:fdd22bb7aa52 278 pDst[2u * i] = (q15_t) outR;
emilmont 1:fdd22bb7aa52 279 pDst[(2u * i) + 1u] = outI >> 15u;
emilmont 1:fdd22bb7aa52 280
emilmont 1:fdd22bb7aa52 281 /* write complex conjugate output */
emilmont 1:fdd22bb7aa52 282 pDst[(4u * fftLen) - (2u * i)] = (q15_t) outR;
emilmont 1:fdd22bb7aa52 283 pDst[((4u * fftLen) - (2u * i)) + 1u] = -(outI >> 15u);
emilmont 1:fdd22bb7aa52 284
emilmont 1:fdd22bb7aa52 285 /* update coefficient pointer */
emilmont 1:fdd22bb7aa52 286 pCoefB = pCoefB + (2u * modifier);
emilmont 1:fdd22bb7aa52 287 pCoefA = pCoefA + (2u * modifier);
emilmont 1:fdd22bb7aa52 288
emilmont 1:fdd22bb7aa52 289 i++;
emilmont 1:fdd22bb7aa52 290
emilmont 1:fdd22bb7aa52 291 }
emilmont 1:fdd22bb7aa52 292
emilmont 1:fdd22bb7aa52 293 pDst[2u * fftLen] = pSrc[0] - pSrc[1];
emilmont 1:fdd22bb7aa52 294 pDst[(2u * fftLen) + 1u] = 0;
emilmont 1:fdd22bb7aa52 295
emilmont 1:fdd22bb7aa52 296 pDst[0] = pSrc[0] + pSrc[1];
emilmont 1:fdd22bb7aa52 297 pDst[1] = 0;
emilmont 1:fdd22bb7aa52 298
emilmont 1:fdd22bb7aa52 299 #endif /* #ifndef ARM_MATH_CM0 */
emilmont 1:fdd22bb7aa52 300
emilmont 1:fdd22bb7aa52 301 }
emilmont 1:fdd22bb7aa52 302
emilmont 1:fdd22bb7aa52 303
emilmont 1:fdd22bb7aa52 304 /**
emilmont 1:fdd22bb7aa52 305 * @brief Core Real IFFT process
emilmont 1:fdd22bb7aa52 306 * @param[in] *pSrc points to the input buffer.
emilmont 1:fdd22bb7aa52 307 * @param[in] fftLen length of FFT.
emilmont 1:fdd22bb7aa52 308 * @param[in] *pATable points to the twiddle Coef A buffer.
emilmont 1:fdd22bb7aa52 309 * @param[in] *pBTable points to the twiddle Coef B buffer.
emilmont 1:fdd22bb7aa52 310 * @param[out] *pDst points to the output buffer.
emilmont 1:fdd22bb7aa52 311 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
emilmont 1:fdd22bb7aa52 312 * @return none.
emilmont 1:fdd22bb7aa52 313 * The function implements a Real IFFT
emilmont 1:fdd22bb7aa52 314 */
emilmont 1:fdd22bb7aa52 315 void arm_split_rifft_q15(
emilmont 1:fdd22bb7aa52 316 q15_t * pSrc,
emilmont 1:fdd22bb7aa52 317 uint32_t fftLen,
emilmont 1:fdd22bb7aa52 318 q15_t * pATable,
emilmont 1:fdd22bb7aa52 319 q15_t * pBTable,
emilmont 1:fdd22bb7aa52 320 q15_t * pDst,
emilmont 1:fdd22bb7aa52 321 uint32_t modifier)
emilmont 1:fdd22bb7aa52 322 {
emilmont 1:fdd22bb7aa52 323 uint32_t i; /* Loop Counter */
emilmont 1:fdd22bb7aa52 324 q31_t outR, outI; /* Temporary variables for output */
emilmont 1:fdd22bb7aa52 325 q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
emilmont 1:fdd22bb7aa52 326 q15_t *pSrc1, *pSrc2;
emilmont 1:fdd22bb7aa52 327 q15_t *pDst1 = &pDst[0];
emilmont 1:fdd22bb7aa52 328
emilmont 1:fdd22bb7aa52 329 pCoefA = &pATable[0];
emilmont 1:fdd22bb7aa52 330 pCoefB = &pBTable[0];
emilmont 1:fdd22bb7aa52 331
emilmont 1:fdd22bb7aa52 332 pSrc1 = &pSrc[0];
emilmont 1:fdd22bb7aa52 333 pSrc2 = &pSrc[2u * fftLen];
emilmont 1:fdd22bb7aa52 334
emilmont 1:fdd22bb7aa52 335 #ifndef ARM_MATH_CM0
emilmont 1:fdd22bb7aa52 336
emilmont 1:fdd22bb7aa52 337 /* Run the below code for Cortex-M4 and Cortex-M3 */
emilmont 1:fdd22bb7aa52 338
emilmont 1:fdd22bb7aa52 339 i = fftLen;
emilmont 1:fdd22bb7aa52 340
emilmont 1:fdd22bb7aa52 341 while(i > 0u)
emilmont 1:fdd22bb7aa52 342 {
emilmont 1:fdd22bb7aa52 343
emilmont 1:fdd22bb7aa52 344 /*
emilmont 1:fdd22bb7aa52 345 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
emilmont 1:fdd22bb7aa52 346 pIn[2 * n - 2 * i] * pBTable[2 * i] -
emilmont 1:fdd22bb7aa52 347 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
emilmont 1:fdd22bb7aa52 348
emilmont 1:fdd22bb7aa52 349 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
emilmont 1:fdd22bb7aa52 350 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
emilmont 1:fdd22bb7aa52 351 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
emilmont 1:fdd22bb7aa52 352
emilmont 1:fdd22bb7aa52 353 */
emilmont 1:fdd22bb7aa52 354
emilmont 1:fdd22bb7aa52 355
emilmont 1:fdd22bb7aa52 356 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 357
emilmont 1:fdd22bb7aa52 358 /* pIn[2 * n - 2 * i] * pBTable[2 * i] -
emilmont 1:fdd22bb7aa52 359 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
emilmont 1:fdd22bb7aa52 360 outR = __SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB));
emilmont 1:fdd22bb7aa52 361
emilmont 1:fdd22bb7aa52 362 #else
emilmont 1:fdd22bb7aa52 363
emilmont 1:fdd22bb7aa52 364 /* -(-pIn[2 * n - 2 * i] * pBTable[2 * i] +
emilmont 1:fdd22bb7aa52 365 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1])) */
emilmont 1:fdd22bb7aa52 366 outR = -(__SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB)));
emilmont 1:fdd22bb7aa52 367
emilmont 1:fdd22bb7aa52 368 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 369
emilmont 1:fdd22bb7aa52 370 /* pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
emilmont 1:fdd22bb7aa52 371 pIn[2 * n - 2 * i] * pBTable[2 * i] */
emilmont 1:fdd22bb7aa52 372 outR = __SMLAD(*__SIMD32(pSrc1), *__SIMD32(pCoefA), outR) >> 15u;
emilmont 1:fdd22bb7aa52 373
emilmont 1:fdd22bb7aa52 374 /*
emilmont 1:fdd22bb7aa52 375 -pIn[2 * n - 2 * i] * pBTable[2 * i + 1] +
emilmont 1:fdd22bb7aa52 376 pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
emilmont 1:fdd22bb7aa52 377 outI = __SMUADX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
emilmont 1:fdd22bb7aa52 378
emilmont 1:fdd22bb7aa52 379 /* pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] */
emilmont 1:fdd22bb7aa52 380
emilmont 1:fdd22bb7aa52 381 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 382
emilmont 1:fdd22bb7aa52 383 outI = __SMLSDX(*__SIMD32(pCoefA), *__SIMD32(pSrc1)++, -outI);
emilmont 1:fdd22bb7aa52 384
emilmont 1:fdd22bb7aa52 385 #else
emilmont 1:fdd22bb7aa52 386
emilmont 1:fdd22bb7aa52 387 outI = __SMLSDX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), -outI);
emilmont 1:fdd22bb7aa52 388
emilmont 1:fdd22bb7aa52 389 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 390 /* write output */
emilmont 1:fdd22bb7aa52 391
emilmont 1:fdd22bb7aa52 392 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 393
emilmont 1:fdd22bb7aa52 394 *__SIMD32(pDst1)++ = __PKHBT(outR, (outI >> 15u), 16);
emilmont 1:fdd22bb7aa52 395
emilmont 1:fdd22bb7aa52 396 #else
emilmont 1:fdd22bb7aa52 397
emilmont 1:fdd22bb7aa52 398 *__SIMD32(pDst1)++ = __PKHBT((outI >> 15u), outR, 16);
emilmont 1:fdd22bb7aa52 399
emilmont 1:fdd22bb7aa52 400 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 401
emilmont 1:fdd22bb7aa52 402 /* update coefficient pointer */
emilmont 1:fdd22bb7aa52 403 pCoefB = pCoefB + (2u * modifier);
emilmont 1:fdd22bb7aa52 404 pCoefA = pCoefA + (2u * modifier);
emilmont 1:fdd22bb7aa52 405
emilmont 1:fdd22bb7aa52 406 i--;
emilmont 1:fdd22bb7aa52 407
emilmont 1:fdd22bb7aa52 408 }
emilmont 1:fdd22bb7aa52 409
emilmont 1:fdd22bb7aa52 410
emilmont 1:fdd22bb7aa52 411 #else
emilmont 1:fdd22bb7aa52 412
emilmont 1:fdd22bb7aa52 413 /* Run the below code for Cortex-M0 */
emilmont 1:fdd22bb7aa52 414
emilmont 1:fdd22bb7aa52 415 i = fftLen;
emilmont 1:fdd22bb7aa52 416
emilmont 1:fdd22bb7aa52 417 while(i > 0u)
emilmont 1:fdd22bb7aa52 418 {
emilmont 1:fdd22bb7aa52 419
emilmont 1:fdd22bb7aa52 420 /*
emilmont 1:fdd22bb7aa52 421 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
emilmont 1:fdd22bb7aa52 422 pIn[2 * n - 2 * i] * pBTable[2 * i] -
emilmont 1:fdd22bb7aa52 423 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
emilmont 1:fdd22bb7aa52 424 */
emilmont 1:fdd22bb7aa52 425
emilmont 1:fdd22bb7aa52 426 outR = *pSrc2 * *pCoefB;
emilmont 1:fdd22bb7aa52 427 outR = outR - (*(pSrc2 + 1) * *(pCoefB + 1));
emilmont 1:fdd22bb7aa52 428 outR = outR + (*pSrc1 * *pCoefA);
emilmont 1:fdd22bb7aa52 429 outR = (outR + (*(pSrc1 + 1) * *(pCoefA + 1))) >> 15;
emilmont 1:fdd22bb7aa52 430
emilmont 1:fdd22bb7aa52 431 /*
emilmont 1:fdd22bb7aa52 432 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
emilmont 1:fdd22bb7aa52 433 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
emilmont 1:fdd22bb7aa52 434 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
emilmont 1:fdd22bb7aa52 435 */
emilmont 1:fdd22bb7aa52 436
emilmont 1:fdd22bb7aa52 437 outI = *(pSrc1 + 1) * *pCoefA;
emilmont 1:fdd22bb7aa52 438 outI = outI - (*pSrc1 * *(pCoefA + 1));
emilmont 1:fdd22bb7aa52 439 outI = outI - (*pSrc2 * *(pCoefB + 1));
emilmont 1:fdd22bb7aa52 440 outI = outI - (*(pSrc2 + 1) * *(pCoefB));
emilmont 1:fdd22bb7aa52 441
emilmont 1:fdd22bb7aa52 442 /* update input pointers */
emilmont 1:fdd22bb7aa52 443 pSrc1 += 2u;
emilmont 1:fdd22bb7aa52 444 pSrc2 -= 2u;
emilmont 1:fdd22bb7aa52 445
emilmont 1:fdd22bb7aa52 446 /* write output */
emilmont 1:fdd22bb7aa52 447 *pDst1++ = (q15_t) outR;
emilmont 1:fdd22bb7aa52 448 *pDst1++ = (q15_t) (outI >> 15);
emilmont 1:fdd22bb7aa52 449
emilmont 1:fdd22bb7aa52 450 /* update coefficient pointer */
emilmont 1:fdd22bb7aa52 451 pCoefB = pCoefB + (2u * modifier);
emilmont 1:fdd22bb7aa52 452 pCoefA = pCoefA + (2u * modifier);
emilmont 1:fdd22bb7aa52 453
emilmont 1:fdd22bb7aa52 454 i--;
emilmont 1:fdd22bb7aa52 455
emilmont 1:fdd22bb7aa52 456 }
emilmont 1:fdd22bb7aa52 457
emilmont 1:fdd22bb7aa52 458 #endif /* #ifndef ARM_MATH_CM0 */
emilmont 1:fdd22bb7aa52 459
emilmont 1:fdd22bb7aa52 460 }