V4.0.1 of the ARM CMSIS DSP libraries. Note that arm_bitreversal2.s, arm_cfft_f32.c and arm_rfft_fast_f32.c had to be removed. arm_bitreversal2.s will not assemble with the online tools. So, the fast f32 FFT functions are not yet available. All the other FFT functions are available.

Dependents:   MPU9150_Example fir_f32 fir_f32 MPU9150_nucleo_noni2cdev ... more

Committer:
emh203
Date:
Mon Jul 28 15:03:15 2014 +0000
Revision:
0:3d9c67d97d6f
1st working commit.   Had to remove arm_bitreversal2.s     arm_cfft_f32.c and arm_rfft_fast_f32.c.    The .s will not assemble.      For now I removed these functions so we could at least have a library for the other functions.

Who changed what in which revision?

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