CMSIS DSP library

Dependents:   performance_timer Surfboard_ gps2rtty Capstone ... more

Legacy Warning

This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.

Committer:
mbed_official
Date:
Fri Nov 20 08:45:18 2015 +0000
Revision:
5:3762170b6d4d
Parent:
3:7a284390b0ce
Synchronized with git revision 2eb940b9a73af188d3004a2575fdfbb05febe62b

Full URL: https://github.com/mbedmicro/mbed/commit/2eb940b9a73af188d3004a2575fdfbb05febe62b/

Added option to build rpc library. closes #1426

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 1:fdd22bb7aa52 1 /* ----------------------------------------------------------------------
mbed_official 5:3762170b6d4d 2 * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
emilmont 1:fdd22bb7aa52 3 *
mbed_official 5:3762170b6d4d 4 * $Date: 19. March 2015
mbed_official 5:3762170b6d4d 5 * $Revision: V.1.4.5
emilmont 1:fdd22bb7aa52 6 *
emilmont 2:da51fb522205 7 * Project: CMSIS DSP Library
emilmont 2:da51fb522205 8 * Title: arm_rfft_q15.c
emilmont 1:fdd22bb7aa52 9 *
emilmont 2:da51fb522205 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 *
mbed_official 3:7a284390b0ce 15 * Redistribution and use in source and binary forms, with or without
mbed_official 3:7a284390b0ce 16 * modification, are permitted provided that the following conditions
mbed_official 3:7a284390b0ce 17 * are met:
mbed_official 3:7a284390b0ce 18 * - Redistributions of source code must retain the above copyright
mbed_official 3:7a284390b0ce 19 * notice, this list of conditions and the following disclaimer.
mbed_official 3:7a284390b0ce 20 * - Redistributions in binary form must reproduce the above copyright
mbed_official 3:7a284390b0ce 21 * notice, this list of conditions and the following disclaimer in
mbed_official 3:7a284390b0ce 22 * the documentation and/or other materials provided with the
mbed_official 3:7a284390b0ce 23 * distribution.
mbed_official 3:7a284390b0ce 24 * - Neither the name of ARM LIMITED nor the names of its contributors
mbed_official 3:7a284390b0ce 25 * may be used to endorse or promote products derived from this
mbed_official 3:7a284390b0ce 26 * software without specific prior written permission.
mbed_official 3:7a284390b0ce 27 *
mbed_official 3:7a284390b0ce 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
mbed_official 3:7a284390b0ce 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
mbed_official 3:7a284390b0ce 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
mbed_official 3:7a284390b0ce 31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
mbed_official 3:7a284390b0ce 32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
mbed_official 3:7a284390b0ce 33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
mbed_official 3:7a284390b0ce 34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
mbed_official 3:7a284390b0ce 35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
mbed_official 3:7a284390b0ce 36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
mbed_official 3:7a284390b0ce 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
mbed_official 3:7a284390b0ce 38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 3:7a284390b0ce 39 * POSSIBILITY OF SUCH DAMAGE.
emilmont 1:fdd22bb7aa52 40 * -------------------------------------------------------------------- */
emilmont 1:fdd22bb7aa52 41
emilmont 1:fdd22bb7aa52 42 #include "arm_math.h"
emilmont 1:fdd22bb7aa52 43
mbed_official 5:3762170b6d4d 44 /*--------------------------------------------------------------------
emilmont 2:da51fb522205 45 * Internal functions prototypes
emilmont 1:fdd22bb7aa52 46 --------------------------------------------------------------------*/
emilmont 1:fdd22bb7aa52 47
emilmont 1:fdd22bb7aa52 48 void arm_split_rfft_q15(
mbed_official 5:3762170b6d4d 49 q15_t * pSrc,
mbed_official 5:3762170b6d4d 50 uint32_t fftLen,
mbed_official 5:3762170b6d4d 51 q15_t * pATable,
mbed_official 5:3762170b6d4d 52 q15_t * pBTable,
mbed_official 5:3762170b6d4d 53 q15_t * pDst,
mbed_official 5:3762170b6d4d 54 uint32_t modifier);
emilmont 1:fdd22bb7aa52 55
emilmont 1:fdd22bb7aa52 56 void arm_split_rifft_q15(
mbed_official 5:3762170b6d4d 57 q15_t * pSrc,
mbed_official 5:3762170b6d4d 58 uint32_t fftLen,
mbed_official 5:3762170b6d4d 59 q15_t * pATable,
mbed_official 5:3762170b6d4d 60 q15_t * pBTable,
mbed_official 5:3762170b6d4d 61 q15_t * pDst,
mbed_official 5:3762170b6d4d 62 uint32_t modifier);
emilmont 1:fdd22bb7aa52 63
emilmont 1:fdd22bb7aa52 64 /**
mbed_official 5:3762170b6d4d 65 * @addtogroup RealFFT
mbed_official 5:3762170b6d4d 66 * @{
mbed_official 5:3762170b6d4d 67 */
emilmont 1:fdd22bb7aa52 68
emilmont 1:fdd22bb7aa52 69 /**
mbed_official 5:3762170b6d4d 70 * @brief Processing function for the Q15 RFFT/RIFFT.
mbed_official 5:3762170b6d4d 71 * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure.
mbed_official 5:3762170b6d4d 72 * @param[in] *pSrc points to the input buffer.
mbed_official 5:3762170b6d4d 73 * @param[out] *pDst points to the output buffer.
mbed_official 5:3762170b6d4d 74 * @return none.
mbed_official 5:3762170b6d4d 75 *
mbed_official 5:3762170b6d4d 76 * \par Input an output formats:
mbed_official 5:3762170b6d4d 77 * \par
mbed_official 5:3762170b6d4d 78 * Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process.
mbed_official 5:3762170b6d4d 79 * Hence the output format is different for different RFFT sizes.
mbed_official 5:3762170b6d4d 80 * 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:
mbed_official 5:3762170b6d4d 81 * \par
mbed_official 5:3762170b6d4d 82 * \image html RFFTQ15.gif "Input and Output Formats for Q15 RFFT"
mbed_official 5:3762170b6d4d 83 * \par
mbed_official 5:3762170b6d4d 84 * \image html RIFFTQ15.gif "Input and Output Formats for Q15 RIFFT"
mbed_official 5:3762170b6d4d 85 */
emilmont 1:fdd22bb7aa52 86
emilmont 1:fdd22bb7aa52 87 void arm_rfft_q15(
mbed_official 5:3762170b6d4d 88 const arm_rfft_instance_q15 * S,
mbed_official 5:3762170b6d4d 89 q15_t * pSrc,
mbed_official 5:3762170b6d4d 90 q15_t * pDst)
emilmont 1:fdd22bb7aa52 91 {
mbed_official 5:3762170b6d4d 92 const arm_cfft_instance_q15 *S_CFFT = S->pCfft;
mbed_official 5:3762170b6d4d 93 uint32_t i;
mbed_official 5:3762170b6d4d 94 uint32_t L2 = S->fftLenReal >> 1;
emilmont 1:fdd22bb7aa52 95
mbed_official 5:3762170b6d4d 96 /* Calculation of RIFFT of input */
mbed_official 5:3762170b6d4d 97 if(S->ifftFlagR == 1u)
emilmont 1:fdd22bb7aa52 98 {
mbed_official 5:3762170b6d4d 99 /* Real IFFT core process */
mbed_official 5:3762170b6d4d 100 arm_split_rifft_q15(pSrc, L2, S->pTwiddleAReal,
mbed_official 5:3762170b6d4d 101 S->pTwiddleBReal, pDst, S->twidCoefRModifier);
mbed_official 5:3762170b6d4d 102
mbed_official 5:3762170b6d4d 103 /* Complex IFFT process */
mbed_official 5:3762170b6d4d 104 arm_cfft_q15(S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR);
mbed_official 5:3762170b6d4d 105
mbed_official 5:3762170b6d4d 106 for(i=0;i<S->fftLenReal;i++)
mbed_official 5:3762170b6d4d 107 {
mbed_official 5:3762170b6d4d 108 pDst[i] = pDst[i] << 1;
mbed_official 5:3762170b6d4d 109 }
emilmont 1:fdd22bb7aa52 110 }
mbed_official 5:3762170b6d4d 111 else
mbed_official 5:3762170b6d4d 112 {
mbed_official 5:3762170b6d4d 113 /* Calculation of RFFT of input */
mbed_official 5:3762170b6d4d 114
mbed_official 5:3762170b6d4d 115 /* Complex FFT process */
mbed_official 5:3762170b6d4d 116 arm_cfft_q15(S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR);
emilmont 1:fdd22bb7aa52 117
mbed_official 5:3762170b6d4d 118 /* Real FFT core process */
mbed_official 5:3762170b6d4d 119 arm_split_rfft_q15(pSrc, L2, S->pTwiddleAReal,
mbed_official 5:3762170b6d4d 120 S->pTwiddleBReal, pDst, S->twidCoefRModifier);
emilmont 1:fdd22bb7aa52 121 }
emilmont 1:fdd22bb7aa52 122 }
emilmont 1:fdd22bb7aa52 123
mbed_official 5:3762170b6d4d 124 /**
mbed_official 5:3762170b6d4d 125 * @} end of RealFFT group
mbed_official 5:3762170b6d4d 126 */
emilmont 1:fdd22bb7aa52 127
emilmont 1:fdd22bb7aa52 128 /**
mbed_official 5:3762170b6d4d 129 * @brief Core Real FFT process
mbed_official 5:3762170b6d4d 130 * @param *pSrc points to the input buffer.
mbed_official 5:3762170b6d4d 131 * @param fftLen length of FFT.
mbed_official 5:3762170b6d4d 132 * @param *pATable points to the A twiddle Coef buffer.
mbed_official 5:3762170b6d4d 133 * @param *pBTable points to the B twiddle Coef buffer.
mbed_official 5:3762170b6d4d 134 * @param *pDst points to the output buffer.
mbed_official 5:3762170b6d4d 135 * @param modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
mbed_official 5:3762170b6d4d 136 * @return none.
mbed_official 5:3762170b6d4d 137 * The function implements a Real FFT
mbed_official 5:3762170b6d4d 138 */
emilmont 1:fdd22bb7aa52 139
emilmont 1:fdd22bb7aa52 140 void arm_split_rfft_q15(
mbed_official 5:3762170b6d4d 141 q15_t * pSrc,
mbed_official 5:3762170b6d4d 142 uint32_t fftLen,
mbed_official 5:3762170b6d4d 143 q15_t * pATable,
mbed_official 5:3762170b6d4d 144 q15_t * pBTable,
mbed_official 5:3762170b6d4d 145 q15_t * pDst,
mbed_official 5:3762170b6d4d 146 uint32_t modifier)
emilmont 1:fdd22bb7aa52 147 {
mbed_official 5:3762170b6d4d 148 uint32_t i; /* Loop Counter */
mbed_official 5:3762170b6d4d 149 q31_t outR, outI; /* Temporary variables for output */
mbed_official 5:3762170b6d4d 150 q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
mbed_official 5:3762170b6d4d 151 q15_t *pSrc1, *pSrc2;
mbed_official 5:3762170b6d4d 152 #ifndef ARM_MATH_CM0_FAMILY
mbed_official 5:3762170b6d4d 153 q15_t *pD1, *pD2;
mbed_official 5:3762170b6d4d 154 #endif
emilmont 1:fdd22bb7aa52 155
mbed_official 5:3762170b6d4d 156 // pSrc[2u * fftLen] = pSrc[0];
mbed_official 5:3762170b6d4d 157 // pSrc[(2u * fftLen) + 1u] = pSrc[1];
emilmont 1:fdd22bb7aa52 158
mbed_official 5:3762170b6d4d 159 pCoefA = &pATable[modifier * 2u];
mbed_official 5:3762170b6d4d 160 pCoefB = &pBTable[modifier * 2u];
emilmont 1:fdd22bb7aa52 161
mbed_official 5:3762170b6d4d 162 pSrc1 = &pSrc[2];
mbed_official 5:3762170b6d4d 163 pSrc2 = &pSrc[(2u * fftLen) - 2u];
emilmont 1:fdd22bb7aa52 164
mbed_official 3:7a284390b0ce 165 #ifndef ARM_MATH_CM0_FAMILY
emilmont 1:fdd22bb7aa52 166
mbed_official 5:3762170b6d4d 167 /* Run the below code for Cortex-M4 and Cortex-M3 */
mbed_official 5:3762170b6d4d 168 i = 1u;
mbed_official 5:3762170b6d4d 169 pD1 = pDst + 2;
mbed_official 5:3762170b6d4d 170 pD2 = pDst + (4u * fftLen) - 2;
emilmont 1:fdd22bb7aa52 171
mbed_official 5:3762170b6d4d 172 for(i = fftLen - 1; i > 0; i--)
mbed_official 5:3762170b6d4d 173 {
mbed_official 5:3762170b6d4d 174 /*
mbed_official 5:3762170b6d4d 175 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
mbed_official 5:3762170b6d4d 176 + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
mbed_official 5:3762170b6d4d 177 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
mbed_official 5:3762170b6d4d 178 */
emilmont 1:fdd22bb7aa52 179
mbed_official 5:3762170b6d4d 180 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
mbed_official 5:3762170b6d4d 181 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
mbed_official 5:3762170b6d4d 182 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
emilmont 1:fdd22bb7aa52 183
emilmont 1:fdd22bb7aa52 184
emilmont 1:fdd22bb7aa52 185 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 186
mbed_official 5:3762170b6d4d 187 /* pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] */
mbed_official 5:3762170b6d4d 188 outR = __SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA));
emilmont 1:fdd22bb7aa52 189
emilmont 1:fdd22bb7aa52 190 #else
emilmont 1:fdd22bb7aa52 191
mbed_official 5:3762170b6d4d 192 /* -(pSrc[2 * i + 1] * pATable[2 * i + 1] - pSrc[2 * i] * pATable[2 * i]) */
mbed_official 5:3762170b6d4d 193 outR = -(__SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA)));
emilmont 1:fdd22bb7aa52 194
emilmont 1:fdd22bb7aa52 195 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 196
mbed_official 5:3762170b6d4d 197 /* pSrc[2 * n - 2 * i] * pBTable[2 * i] +
mbed_official 5:3762170b6d4d 198 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
mbed_official 5:3762170b6d4d 199 outR = __SMLAD(*__SIMD32(pSrc2), *__SIMD32(pCoefB), outR) >> 16u;
emilmont 1:fdd22bb7aa52 200
mbed_official 5:3762170b6d4d 201 /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
mbed_official 5:3762170b6d4d 202 pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
emilmont 1:fdd22bb7aa52 203
emilmont 1:fdd22bb7aa52 204 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 205
mbed_official 5:3762170b6d4d 206 outI = __SMUSDX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
emilmont 1:fdd22bb7aa52 207
emilmont 1:fdd22bb7aa52 208 #else
emilmont 1:fdd22bb7aa52 209
mbed_official 5:3762170b6d4d 210 outI = __SMUSDX(*__SIMD32(pCoefB), *__SIMD32(pSrc2)--);
emilmont 1:fdd22bb7aa52 211
emilmont 1:fdd22bb7aa52 212 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 213
mbed_official 5:3762170b6d4d 214 /* (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] */
mbed_official 5:3762170b6d4d 215 outI = __SMLADX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), outI);
emilmont 1:fdd22bb7aa52 216
mbed_official 5:3762170b6d4d 217 /* write output */
mbed_official 5:3762170b6d4d 218 *pD1++ = (q15_t) outR;
mbed_official 5:3762170b6d4d 219 *pD1++ = outI >> 16u;
emilmont 1:fdd22bb7aa52 220
mbed_official 5:3762170b6d4d 221 /* write complex conjugate output */
mbed_official 5:3762170b6d4d 222 pD2[0] = (q15_t) outR;
mbed_official 5:3762170b6d4d 223 pD2[1] = -(outI >> 16u);
mbed_official 5:3762170b6d4d 224 pD2 -= 2;
emilmont 1:fdd22bb7aa52 225
mbed_official 5:3762170b6d4d 226 /* update coefficient pointer */
mbed_official 5:3762170b6d4d 227 pCoefB = pCoefB + (2u * modifier);
mbed_official 5:3762170b6d4d 228 pCoefA = pCoefA + (2u * modifier);
mbed_official 5:3762170b6d4d 229 }
emilmont 1:fdd22bb7aa52 230
mbed_official 5:3762170b6d4d 231 pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
mbed_official 5:3762170b6d4d 232 pDst[(2u * fftLen) + 1u] = 0;
emilmont 1:fdd22bb7aa52 233
mbed_official 5:3762170b6d4d 234 pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
mbed_official 5:3762170b6d4d 235 pDst[1] = 0;
emilmont 1:fdd22bb7aa52 236
emilmont 1:fdd22bb7aa52 237 #else
emilmont 1:fdd22bb7aa52 238
mbed_official 5:3762170b6d4d 239 /* Run the below code for Cortex-M0 */
mbed_official 5:3762170b6d4d 240 i = 1u;
emilmont 1:fdd22bb7aa52 241
mbed_official 5:3762170b6d4d 242 while(i < fftLen)
mbed_official 5:3762170b6d4d 243 {
mbed_official 5:3762170b6d4d 244 /*
mbed_official 5:3762170b6d4d 245 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
mbed_official 5:3762170b6d4d 246 + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
mbed_official 5:3762170b6d4d 247 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
mbed_official 5:3762170b6d4d 248 */
emilmont 1:fdd22bb7aa52 249
mbed_official 5:3762170b6d4d 250 outR = *pSrc1 * *pCoefA;
mbed_official 5:3762170b6d4d 251 outR = outR - (*(pSrc1 + 1) * *(pCoefA + 1));
mbed_official 5:3762170b6d4d 252 outR = outR + (*pSrc2 * *pCoefB);
mbed_official 5:3762170b6d4d 253 outR = (outR + (*(pSrc2 + 1) * *(pCoefB + 1))) >> 16;
emilmont 1:fdd22bb7aa52 254
emilmont 1:fdd22bb7aa52 255
mbed_official 5:3762170b6d4d 256 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
mbed_official 5:3762170b6d4d 257 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
mbed_official 5:3762170b6d4d 258 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
mbed_official 5:3762170b6d4d 259 */
emilmont 1:fdd22bb7aa52 260
mbed_official 5:3762170b6d4d 261 outI = *pSrc2 * *(pCoefB + 1);
mbed_official 5:3762170b6d4d 262 outI = outI - (*(pSrc2 + 1) * *pCoefB);
mbed_official 5:3762170b6d4d 263 outI = outI + (*(pSrc1 + 1) * *pCoefA);
mbed_official 5:3762170b6d4d 264 outI = outI + (*pSrc1 * *(pCoefA + 1));
emilmont 1:fdd22bb7aa52 265
mbed_official 5:3762170b6d4d 266 /* update input pointers */
mbed_official 5:3762170b6d4d 267 pSrc1 += 2u;
mbed_official 5:3762170b6d4d 268 pSrc2 -= 2u;
emilmont 1:fdd22bb7aa52 269
mbed_official 5:3762170b6d4d 270 /* write output */
mbed_official 5:3762170b6d4d 271 pDst[2u * i] = (q15_t) outR;
mbed_official 5:3762170b6d4d 272 pDst[(2u * i) + 1u] = outI >> 16u;
emilmont 1:fdd22bb7aa52 273
mbed_official 5:3762170b6d4d 274 /* write complex conjugate output */
mbed_official 5:3762170b6d4d 275 pDst[(4u * fftLen) - (2u * i)] = (q15_t) outR;
mbed_official 5:3762170b6d4d 276 pDst[((4u * fftLen) - (2u * i)) + 1u] = -(outI >> 16u);
emilmont 1:fdd22bb7aa52 277
mbed_official 5:3762170b6d4d 278 /* update coefficient pointer */
mbed_official 5:3762170b6d4d 279 pCoefB = pCoefB + (2u * modifier);
mbed_official 5:3762170b6d4d 280 pCoefA = pCoefA + (2u * modifier);
emilmont 1:fdd22bb7aa52 281
mbed_official 5:3762170b6d4d 282 i++;
mbed_official 5:3762170b6d4d 283 }
emilmont 1:fdd22bb7aa52 284
mbed_official 5:3762170b6d4d 285 pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
mbed_official 5:3762170b6d4d 286 pDst[(2u * fftLen) + 1u] = 0;
mbed_official 5:3762170b6d4d 287
mbed_official 5:3762170b6d4d 288 pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
mbed_official 5:3762170b6d4d 289 pDst[1] = 0;
emilmont 1:fdd22bb7aa52 290
mbed_official 3:7a284390b0ce 291 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
emilmont 1:fdd22bb7aa52 292 }
emilmont 1:fdd22bb7aa52 293
emilmont 1:fdd22bb7aa52 294
emilmont 1:fdd22bb7aa52 295 /**
mbed_official 5:3762170b6d4d 296 * @brief Core Real IFFT process
mbed_official 5:3762170b6d4d 297 * @param[in] *pSrc points to the input buffer.
mbed_official 5:3762170b6d4d 298 * @param[in] fftLen length of FFT.
mbed_official 5:3762170b6d4d 299 * @param[in] *pATable points to the twiddle Coef A buffer.
mbed_official 5:3762170b6d4d 300 * @param[in] *pBTable points to the twiddle Coef B buffer.
mbed_official 5:3762170b6d4d 301 * @param[out] *pDst points to the output buffer.
mbed_official 5:3762170b6d4d 302 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
mbed_official 5:3762170b6d4d 303 * @return none.
mbed_official 5:3762170b6d4d 304 * The function implements a Real IFFT
mbed_official 5:3762170b6d4d 305 */
emilmont 1:fdd22bb7aa52 306 void arm_split_rifft_q15(
mbed_official 5:3762170b6d4d 307 q15_t * pSrc,
mbed_official 5:3762170b6d4d 308 uint32_t fftLen,
mbed_official 5:3762170b6d4d 309 q15_t * pATable,
mbed_official 5:3762170b6d4d 310 q15_t * pBTable,
mbed_official 5:3762170b6d4d 311 q15_t * pDst,
mbed_official 5:3762170b6d4d 312 uint32_t modifier)
emilmont 1:fdd22bb7aa52 313 {
mbed_official 5:3762170b6d4d 314 uint32_t i; /* Loop Counter */
mbed_official 5:3762170b6d4d 315 q31_t outR, outI; /* Temporary variables for output */
mbed_official 5:3762170b6d4d 316 q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
mbed_official 5:3762170b6d4d 317 q15_t *pSrc1, *pSrc2;
mbed_official 5:3762170b6d4d 318 q15_t *pDst1 = &pDst[0];
emilmont 1:fdd22bb7aa52 319
mbed_official 5:3762170b6d4d 320 pCoefA = &pATable[0];
mbed_official 5:3762170b6d4d 321 pCoefB = &pBTable[0];
emilmont 1:fdd22bb7aa52 322
mbed_official 5:3762170b6d4d 323 pSrc1 = &pSrc[0];
mbed_official 5:3762170b6d4d 324 pSrc2 = &pSrc[2u * fftLen];
emilmont 1:fdd22bb7aa52 325
mbed_official 3:7a284390b0ce 326 #ifndef ARM_MATH_CM0_FAMILY
emilmont 1:fdd22bb7aa52 327
mbed_official 5:3762170b6d4d 328 /* Run the below code for Cortex-M4 and Cortex-M3 */
mbed_official 5:3762170b6d4d 329 i = fftLen;
emilmont 1:fdd22bb7aa52 330
mbed_official 5:3762170b6d4d 331 while(i > 0u)
mbed_official 5:3762170b6d4d 332 {
mbed_official 5:3762170b6d4d 333 /*
mbed_official 5:3762170b6d4d 334 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
mbed_official 5:3762170b6d4d 335 pIn[2 * n - 2 * i] * pBTable[2 * i] -
mbed_official 5:3762170b6d4d 336 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
emilmont 1:fdd22bb7aa52 337
mbed_official 5:3762170b6d4d 338 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
mbed_official 5:3762170b6d4d 339 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
mbed_official 5:3762170b6d4d 340 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
mbed_official 5:3762170b6d4d 341 */
emilmont 1:fdd22bb7aa52 342
emilmont 1:fdd22bb7aa52 343
emilmont 1:fdd22bb7aa52 344 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 345
mbed_official 5:3762170b6d4d 346 /* pIn[2 * n - 2 * i] * pBTable[2 * i] -
mbed_official 5:3762170b6d4d 347 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
mbed_official 5:3762170b6d4d 348 outR = __SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB));
emilmont 1:fdd22bb7aa52 349
emilmont 1:fdd22bb7aa52 350 #else
emilmont 1:fdd22bb7aa52 351
mbed_official 5:3762170b6d4d 352 /* -(-pIn[2 * n - 2 * i] * pBTable[2 * i] +
mbed_official 5:3762170b6d4d 353 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1])) */
mbed_official 5:3762170b6d4d 354 outR = -(__SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB)));
emilmont 1:fdd22bb7aa52 355
emilmont 1:fdd22bb7aa52 356 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 357
mbed_official 5:3762170b6d4d 358 /* pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
mbed_official 5:3762170b6d4d 359 pIn[2 * n - 2 * i] * pBTable[2 * i] */
mbed_official 5:3762170b6d4d 360 outR = __SMLAD(*__SIMD32(pSrc1), *__SIMD32(pCoefA), outR) >> 16u;
emilmont 1:fdd22bb7aa52 361
mbed_official 5:3762170b6d4d 362 /*
mbed_official 5:3762170b6d4d 363 -pIn[2 * n - 2 * i] * pBTable[2 * i + 1] +
mbed_official 5:3762170b6d4d 364 pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
mbed_official 5:3762170b6d4d 365 outI = __SMUADX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
emilmont 1:fdd22bb7aa52 366
mbed_official 5:3762170b6d4d 367 /* pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] */
emilmont 1:fdd22bb7aa52 368
emilmont 1:fdd22bb7aa52 369 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 370
mbed_official 5:3762170b6d4d 371 outI = __SMLSDX(*__SIMD32(pCoefA), *__SIMD32(pSrc1)++, -outI);
emilmont 1:fdd22bb7aa52 372
emilmont 1:fdd22bb7aa52 373 #else
emilmont 1:fdd22bb7aa52 374
mbed_official 5:3762170b6d4d 375 outI = __SMLSDX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), -outI);
emilmont 1:fdd22bb7aa52 376
emilmont 1:fdd22bb7aa52 377 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
mbed_official 5:3762170b6d4d 378 /* write output */
emilmont 1:fdd22bb7aa52 379
emilmont 1:fdd22bb7aa52 380 #ifndef ARM_MATH_BIG_ENDIAN
emilmont 1:fdd22bb7aa52 381
mbed_official 5:3762170b6d4d 382 *__SIMD32(pDst1)++ = __PKHBT(outR, (outI >> 16u), 16);
emilmont 1:fdd22bb7aa52 383
emilmont 1:fdd22bb7aa52 384 #else
emilmont 1:fdd22bb7aa52 385
mbed_official 5:3762170b6d4d 386 *__SIMD32(pDst1)++ = __PKHBT((outI >> 16u), outR, 16);
emilmont 1:fdd22bb7aa52 387
emilmont 1:fdd22bb7aa52 388 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
emilmont 1:fdd22bb7aa52 389
mbed_official 5:3762170b6d4d 390 /* update coefficient pointer */
mbed_official 5:3762170b6d4d 391 pCoefB = pCoefB + (2u * modifier);
mbed_official 5:3762170b6d4d 392 pCoefA = pCoefA + (2u * modifier);
emilmont 1:fdd22bb7aa52 393
mbed_official 5:3762170b6d4d 394 i--;
mbed_official 5:3762170b6d4d 395 }
emilmont 1:fdd22bb7aa52 396 #else
mbed_official 5:3762170b6d4d 397 /* Run the below code for Cortex-M0 */
mbed_official 5:3762170b6d4d 398 i = fftLen;
emilmont 1:fdd22bb7aa52 399
mbed_official 5:3762170b6d4d 400 while(i > 0u)
mbed_official 5:3762170b6d4d 401 {
mbed_official 5:3762170b6d4d 402 /*
mbed_official 5:3762170b6d4d 403 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
mbed_official 5:3762170b6d4d 404 pIn[2 * n - 2 * i] * pBTable[2 * i] -
mbed_official 5:3762170b6d4d 405 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
mbed_official 5:3762170b6d4d 406 */
emilmont 1:fdd22bb7aa52 407
mbed_official 5:3762170b6d4d 408 outR = *pSrc2 * *pCoefB;
mbed_official 5:3762170b6d4d 409 outR = outR - (*(pSrc2 + 1) * *(pCoefB + 1));
mbed_official 5:3762170b6d4d 410 outR = outR + (*pSrc1 * *pCoefA);
mbed_official 5:3762170b6d4d 411 outR = (outR + (*(pSrc1 + 1) * *(pCoefA + 1))) >> 16;
emilmont 1:fdd22bb7aa52 412
mbed_official 5:3762170b6d4d 413 /*
mbed_official 5:3762170b6d4d 414 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
mbed_official 5:3762170b6d4d 415 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
mbed_official 5:3762170b6d4d 416 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
mbed_official 5:3762170b6d4d 417 */
emilmont 1:fdd22bb7aa52 418
mbed_official 5:3762170b6d4d 419 outI = *(pSrc1 + 1) * *pCoefA;
mbed_official 5:3762170b6d4d 420 outI = outI - (*pSrc1 * *(pCoefA + 1));
mbed_official 5:3762170b6d4d 421 outI = outI - (*pSrc2 * *(pCoefB + 1));
mbed_official 5:3762170b6d4d 422 outI = outI - (*(pSrc2 + 1) * *(pCoefB));
emilmont 1:fdd22bb7aa52 423
mbed_official 5:3762170b6d4d 424 /* update input pointers */
mbed_official 5:3762170b6d4d 425 pSrc1 += 2u;
mbed_official 5:3762170b6d4d 426 pSrc2 -= 2u;
emilmont 1:fdd22bb7aa52 427
mbed_official 5:3762170b6d4d 428 /* write output */
mbed_official 5:3762170b6d4d 429 *pDst1++ = (q15_t) outR;
mbed_official 5:3762170b6d4d 430 *pDst1++ = (q15_t) (outI >> 16);
emilmont 1:fdd22bb7aa52 431
mbed_official 5:3762170b6d4d 432 /* update coefficient pointer */
mbed_official 5:3762170b6d4d 433 pCoefB = pCoefB + (2u * modifier);
mbed_official 5:3762170b6d4d 434 pCoefA = pCoefA + (2u * modifier);
emilmont 1:fdd22bb7aa52 435
mbed_official 5:3762170b6d4d 436 i--;
mbed_official 5:3762170b6d4d 437 }
mbed_official 3:7a284390b0ce 438 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
emilmont 1:fdd22bb7aa52 439 }