Audio Demo with DISCO Board, takes control samples, waits for user input, samples regularly.

Dependencies:   CMSIS_DSP_401 STM32L4xx_HAL_Driver mbed-src_DISO_AUDIO_DEMO

Committer:
EricLew
Date:
Sun Dec 13 19:12:11 2015 +0000
Revision:
0:3eee9435dd17
Audio Demo using DISCO Board

Who changed what in which revision?

UserRevisionLine numberNew contents of line
EricLew 0:3eee9435dd17 1 /* ----------------------------------------------------------------------
EricLew 0:3eee9435dd17 2 * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
EricLew 0:3eee9435dd17 3 *
EricLew 0:3eee9435dd17 4 * $Date: 19. March 2015
EricLew 0:3eee9435dd17 5 * $Revision: V.1.4.5
EricLew 0:3eee9435dd17 6 *
EricLew 0:3eee9435dd17 7 * Project: CMSIS DSP Library
EricLew 0:3eee9435dd17 8 * Title: arm_cfft_f32.c
EricLew 0:3eee9435dd17 9 *
EricLew 0:3eee9435dd17 10 * Description: Combined Radix Decimation in Frequency CFFT Floating point processing function
EricLew 0:3eee9435dd17 11 *
EricLew 0:3eee9435dd17 12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
EricLew 0:3eee9435dd17 13 *
EricLew 0:3eee9435dd17 14 * Redistribution and use in source and binary forms, with or without
EricLew 0:3eee9435dd17 15 * modification, are permitted provided that the following conditions
EricLew 0:3eee9435dd17 16 * are met:
EricLew 0:3eee9435dd17 17 * - Redistributions of source code must retain the above copyright
EricLew 0:3eee9435dd17 18 * notice, this list of conditions and the following disclaimer.
EricLew 0:3eee9435dd17 19 * - Redistributions in binary form must reproduce the above copyright
EricLew 0:3eee9435dd17 20 * notice, this list of conditions and the following disclaimer in
EricLew 0:3eee9435dd17 21 * the documentation and/or other materials provided with the
EricLew 0:3eee9435dd17 22 * distribution.
EricLew 0:3eee9435dd17 23 * - Neither the name of ARM LIMITED nor the names of its contributors
EricLew 0:3eee9435dd17 24 * may be used to endorse or promote products derived from this
EricLew 0:3eee9435dd17 25 * software without specific prior written permission.
EricLew 0:3eee9435dd17 26 *
EricLew 0:3eee9435dd17 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
EricLew 0:3eee9435dd17 28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
EricLew 0:3eee9435dd17 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
EricLew 0:3eee9435dd17 30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
EricLew 0:3eee9435dd17 31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
EricLew 0:3eee9435dd17 32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
EricLew 0:3eee9435dd17 33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
EricLew 0:3eee9435dd17 34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
EricLew 0:3eee9435dd17 35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
EricLew 0:3eee9435dd17 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
EricLew 0:3eee9435dd17 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
EricLew 0:3eee9435dd17 38 * POSSIBILITY OF SUCH DAMAGE.
EricLew 0:3eee9435dd17 39 * -------------------------------------------------------------------- */
EricLew 0:3eee9435dd17 40
EricLew 0:3eee9435dd17 41 #include "arm_math.h"
EricLew 0:3eee9435dd17 42 #include "arm_common_tables.h"
EricLew 0:3eee9435dd17 43
EricLew 0:3eee9435dd17 44 extern void arm_radix8_butterfly_f32(
EricLew 0:3eee9435dd17 45 float32_t * pSrc,
EricLew 0:3eee9435dd17 46 uint16_t fftLen,
EricLew 0:3eee9435dd17 47 const float32_t * pCoef,
EricLew 0:3eee9435dd17 48 uint16_t twidCoefModifier);
EricLew 0:3eee9435dd17 49
EricLew 0:3eee9435dd17 50 extern void arm_bitreversal_32(
EricLew 0:3eee9435dd17 51 uint32_t * pSrc,
EricLew 0:3eee9435dd17 52 const uint16_t bitRevLen,
EricLew 0:3eee9435dd17 53 const uint16_t * pBitRevTable);
EricLew 0:3eee9435dd17 54
EricLew 0:3eee9435dd17 55 /**
EricLew 0:3eee9435dd17 56 * @ingroup groupTransforms
EricLew 0:3eee9435dd17 57 */
EricLew 0:3eee9435dd17 58
EricLew 0:3eee9435dd17 59 /**
EricLew 0:3eee9435dd17 60 * @defgroup ComplexFFT Complex FFT Functions
EricLew 0:3eee9435dd17 61 *
EricLew 0:3eee9435dd17 62 * \par
EricLew 0:3eee9435dd17 63 * The Fast Fourier Transform (FFT) is an efficient algorithm for computing the
EricLew 0:3eee9435dd17 64 * Discrete Fourier Transform (DFT). The FFT can be orders of magnitude faster
EricLew 0:3eee9435dd17 65 * than the DFT, especially for long lengths.
EricLew 0:3eee9435dd17 66 * The algorithms described in this section
EricLew 0:3eee9435dd17 67 * operate on complex data. A separate set of functions is devoted to handling
EricLew 0:3eee9435dd17 68 * of real sequences.
EricLew 0:3eee9435dd17 69 * \par
EricLew 0:3eee9435dd17 70 * There are separate algorithms for handling floating-point, Q15, and Q31 data
EricLew 0:3eee9435dd17 71 * types. The algorithms available for each data type are described next.
EricLew 0:3eee9435dd17 72 * \par
EricLew 0:3eee9435dd17 73 * The FFT functions operate in-place. That is, the array holding the input data
EricLew 0:3eee9435dd17 74 * will also be used to hold the corresponding result. The input data is complex
EricLew 0:3eee9435dd17 75 * and contains <code>2*fftLen</code> interleaved values as shown below.
EricLew 0:3eee9435dd17 76 * <pre> {real[0], imag[0], real[1], imag[1],..} </pre>
EricLew 0:3eee9435dd17 77 * The FFT result will be contained in the same array and the frequency domain
EricLew 0:3eee9435dd17 78 * values will have the same interleaving.
EricLew 0:3eee9435dd17 79 *
EricLew 0:3eee9435dd17 80 * \par Floating-point
EricLew 0:3eee9435dd17 81 * The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-8
EricLew 0:3eee9435dd17 82 * stages are performed along with a single radix-2 or radix-4 stage, as needed.
EricLew 0:3eee9435dd17 83 * The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
EricLew 0:3eee9435dd17 84 * a different twiddle factor table.
EricLew 0:3eee9435dd17 85 * \par
EricLew 0:3eee9435dd17 86 * The function uses the standard FFT definition and output values may grow by a
EricLew 0:3eee9435dd17 87 * factor of <code>fftLen</code> when computing the forward transform. The
EricLew 0:3eee9435dd17 88 * inverse transform includes a scale of <code>1/fftLen</code> as part of the
EricLew 0:3eee9435dd17 89 * calculation and this matches the textbook definition of the inverse FFT.
EricLew 0:3eee9435dd17 90 * \par
EricLew 0:3eee9435dd17 91 * Pre-initialized data structures containing twiddle factors and bit reversal
EricLew 0:3eee9435dd17 92 * tables are provided and defined in <code>arm_const_structs.h</code>. Include
EricLew 0:3eee9435dd17 93 * this header in your function and then pass one of the constant structures as
EricLew 0:3eee9435dd17 94 * an argument to arm_cfft_f32. For example:
EricLew 0:3eee9435dd17 95 * \par
EricLew 0:3eee9435dd17 96 * <code>arm_cfft_f32(arm_cfft_sR_f32_len64, pSrc, 1, 1)</code>
EricLew 0:3eee9435dd17 97 * \par
EricLew 0:3eee9435dd17 98 * computes a 64-point inverse complex FFT including bit reversal.
EricLew 0:3eee9435dd17 99 * The data structures are treated as constant data and not modified during the
EricLew 0:3eee9435dd17 100 * calculation. The same data structure can be reused for multiple transforms
EricLew 0:3eee9435dd17 101 * including mixing forward and inverse transforms.
EricLew 0:3eee9435dd17 102 * \par
EricLew 0:3eee9435dd17 103 * Earlier releases of the library provided separate radix-2 and radix-4
EricLew 0:3eee9435dd17 104 * algorithms that operated on floating-point data. These functions are still
EricLew 0:3eee9435dd17 105 * provided but are deprecated. The older functions are slower and less general
EricLew 0:3eee9435dd17 106 * than the new functions.
EricLew 0:3eee9435dd17 107 * \par
EricLew 0:3eee9435dd17 108 * An example of initialization of the constants for the arm_cfft_f32 function follows:
EricLew 0:3eee9435dd17 109 * \code
EricLew 0:3eee9435dd17 110 * const static arm_cfft_instance_f32 *S;
EricLew 0:3eee9435dd17 111 * ...
EricLew 0:3eee9435dd17 112 * switch (length) {
EricLew 0:3eee9435dd17 113 * case 16:
EricLew 0:3eee9435dd17 114 * S = &arm_cfft_sR_f32_len16;
EricLew 0:3eee9435dd17 115 * break;
EricLew 0:3eee9435dd17 116 * case 32:
EricLew 0:3eee9435dd17 117 * S = &arm_cfft_sR_f32_len32;
EricLew 0:3eee9435dd17 118 * break;
EricLew 0:3eee9435dd17 119 * case 64:
EricLew 0:3eee9435dd17 120 * S = &arm_cfft_sR_f32_len64;
EricLew 0:3eee9435dd17 121 * break;
EricLew 0:3eee9435dd17 122 * case 128:
EricLew 0:3eee9435dd17 123 * S = &arm_cfft_sR_f32_len128;
EricLew 0:3eee9435dd17 124 * break;
EricLew 0:3eee9435dd17 125 * case 256:
EricLew 0:3eee9435dd17 126 * S = &arm_cfft_sR_f32_len256;
EricLew 0:3eee9435dd17 127 * break;
EricLew 0:3eee9435dd17 128 * case 512:
EricLew 0:3eee9435dd17 129 * S = &arm_cfft_sR_f32_len512;
EricLew 0:3eee9435dd17 130 * break;
EricLew 0:3eee9435dd17 131 * case 1024:
EricLew 0:3eee9435dd17 132 * S = &arm_cfft_sR_f32_len1024;
EricLew 0:3eee9435dd17 133 * break;
EricLew 0:3eee9435dd17 134 * case 2048:
EricLew 0:3eee9435dd17 135 * S = &arm_cfft_sR_f32_len2048;
EricLew 0:3eee9435dd17 136 * break;
EricLew 0:3eee9435dd17 137 * case 4096:
EricLew 0:3eee9435dd17 138 * S = &arm_cfft_sR_f32_len4096;
EricLew 0:3eee9435dd17 139 * break;
EricLew 0:3eee9435dd17 140 * }
EricLew 0:3eee9435dd17 141 * \endcode
EricLew 0:3eee9435dd17 142 * \par Q15 and Q31
EricLew 0:3eee9435dd17 143 * The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-4
EricLew 0:3eee9435dd17 144 * stages are performed along with a single radix-2 stage, as needed.
EricLew 0:3eee9435dd17 145 * The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
EricLew 0:3eee9435dd17 146 * a different twiddle factor table.
EricLew 0:3eee9435dd17 147 * \par
EricLew 0:3eee9435dd17 148 * The function uses the standard FFT definition and output values may grow by a
EricLew 0:3eee9435dd17 149 * factor of <code>fftLen</code> when computing the forward transform. The
EricLew 0:3eee9435dd17 150 * inverse transform includes a scale of <code>1/fftLen</code> as part of the
EricLew 0:3eee9435dd17 151 * calculation and this matches the textbook definition of the inverse FFT.
EricLew 0:3eee9435dd17 152 * \par
EricLew 0:3eee9435dd17 153 * Pre-initialized data structures containing twiddle factors and bit reversal
EricLew 0:3eee9435dd17 154 * tables are provided and defined in <code>arm_const_structs.h</code>. Include
EricLew 0:3eee9435dd17 155 * this header in your function and then pass one of the constant structures as
EricLew 0:3eee9435dd17 156 * an argument to arm_cfft_q31. For example:
EricLew 0:3eee9435dd17 157 * \par
EricLew 0:3eee9435dd17 158 * <code>arm_cfft_q31(arm_cfft_sR_q31_len64, pSrc, 1, 1)</code>
EricLew 0:3eee9435dd17 159 * \par
EricLew 0:3eee9435dd17 160 * computes a 64-point inverse complex FFT including bit reversal.
EricLew 0:3eee9435dd17 161 * The data structures are treated as constant data and not modified during the
EricLew 0:3eee9435dd17 162 * calculation. The same data structure can be reused for multiple transforms
EricLew 0:3eee9435dd17 163 * including mixing forward and inverse transforms.
EricLew 0:3eee9435dd17 164 * \par
EricLew 0:3eee9435dd17 165 * Earlier releases of the library provided separate radix-2 and radix-4
EricLew 0:3eee9435dd17 166 * algorithms that operated on floating-point data. These functions are still
EricLew 0:3eee9435dd17 167 * provided but are deprecated. The older functions are slower and less general
EricLew 0:3eee9435dd17 168 * than the new functions.
EricLew 0:3eee9435dd17 169 * \par
EricLew 0:3eee9435dd17 170 * An example of initialization of the constants for the arm_cfft_q31 function follows:
EricLew 0:3eee9435dd17 171 * \code
EricLew 0:3eee9435dd17 172 * const static arm_cfft_instance_q31 *S;
EricLew 0:3eee9435dd17 173 * ...
EricLew 0:3eee9435dd17 174 * switch (length) {
EricLew 0:3eee9435dd17 175 * case 16:
EricLew 0:3eee9435dd17 176 * S = &arm_cfft_sR_q31_len16;
EricLew 0:3eee9435dd17 177 * break;
EricLew 0:3eee9435dd17 178 * case 32:
EricLew 0:3eee9435dd17 179 * S = &arm_cfft_sR_q31_len32;
EricLew 0:3eee9435dd17 180 * break;
EricLew 0:3eee9435dd17 181 * case 64:
EricLew 0:3eee9435dd17 182 * S = &arm_cfft_sR_q31_len64;
EricLew 0:3eee9435dd17 183 * break;
EricLew 0:3eee9435dd17 184 * case 128:
EricLew 0:3eee9435dd17 185 * S = &arm_cfft_sR_q31_len128;
EricLew 0:3eee9435dd17 186 * break;
EricLew 0:3eee9435dd17 187 * case 256:
EricLew 0:3eee9435dd17 188 * S = &arm_cfft_sR_q31_len256;
EricLew 0:3eee9435dd17 189 * break;
EricLew 0:3eee9435dd17 190 * case 512:
EricLew 0:3eee9435dd17 191 * S = &arm_cfft_sR_q31_len512;
EricLew 0:3eee9435dd17 192 * break;
EricLew 0:3eee9435dd17 193 * case 1024:
EricLew 0:3eee9435dd17 194 * S = &arm_cfft_sR_q31_len1024;
EricLew 0:3eee9435dd17 195 * break;
EricLew 0:3eee9435dd17 196 * case 2048:
EricLew 0:3eee9435dd17 197 * S = &arm_cfft_sR_q31_len2048;
EricLew 0:3eee9435dd17 198 * break;
EricLew 0:3eee9435dd17 199 * case 4096:
EricLew 0:3eee9435dd17 200 * S = &arm_cfft_sR_q31_len4096;
EricLew 0:3eee9435dd17 201 * break;
EricLew 0:3eee9435dd17 202 * }
EricLew 0:3eee9435dd17 203 * \endcode
EricLew 0:3eee9435dd17 204 *
EricLew 0:3eee9435dd17 205 */
EricLew 0:3eee9435dd17 206
EricLew 0:3eee9435dd17 207 void arm_cfft_radix8by2_f32( arm_cfft_instance_f32 * S, float32_t * p1)
EricLew 0:3eee9435dd17 208 {
EricLew 0:3eee9435dd17 209 uint32_t L = S->fftLen;
EricLew 0:3eee9435dd17 210 float32_t * pCol1, * pCol2, * pMid1, * pMid2;
EricLew 0:3eee9435dd17 211 float32_t * p2 = p1 + L;
EricLew 0:3eee9435dd17 212 const float32_t * tw = (float32_t *) S->pTwiddle;
EricLew 0:3eee9435dd17 213 float32_t t1[4], t2[4], t3[4], t4[4], twR, twI;
EricLew 0:3eee9435dd17 214 float32_t m0, m1, m2, m3;
EricLew 0:3eee9435dd17 215 uint32_t l;
EricLew 0:3eee9435dd17 216
EricLew 0:3eee9435dd17 217 pCol1 = p1;
EricLew 0:3eee9435dd17 218 pCol2 = p2;
EricLew 0:3eee9435dd17 219
EricLew 0:3eee9435dd17 220 // Define new length
EricLew 0:3eee9435dd17 221 L >>= 1;
EricLew 0:3eee9435dd17 222 // Initialize mid pointers
EricLew 0:3eee9435dd17 223 pMid1 = p1 + L;
EricLew 0:3eee9435dd17 224 pMid2 = p2 + L;
EricLew 0:3eee9435dd17 225
EricLew 0:3eee9435dd17 226 // do two dot Fourier transform
EricLew 0:3eee9435dd17 227 for ( l = L >> 2; l > 0; l-- )
EricLew 0:3eee9435dd17 228 {
EricLew 0:3eee9435dd17 229 t1[0] = p1[0];
EricLew 0:3eee9435dd17 230 t1[1] = p1[1];
EricLew 0:3eee9435dd17 231 t1[2] = p1[2];
EricLew 0:3eee9435dd17 232 t1[3] = p1[3];
EricLew 0:3eee9435dd17 233
EricLew 0:3eee9435dd17 234 t2[0] = p2[0];
EricLew 0:3eee9435dd17 235 t2[1] = p2[1];
EricLew 0:3eee9435dd17 236 t2[2] = p2[2];
EricLew 0:3eee9435dd17 237 t2[3] = p2[3];
EricLew 0:3eee9435dd17 238
EricLew 0:3eee9435dd17 239 t3[0] = pMid1[0];
EricLew 0:3eee9435dd17 240 t3[1] = pMid1[1];
EricLew 0:3eee9435dd17 241 t3[2] = pMid1[2];
EricLew 0:3eee9435dd17 242 t3[3] = pMid1[3];
EricLew 0:3eee9435dd17 243
EricLew 0:3eee9435dd17 244 t4[0] = pMid2[0];
EricLew 0:3eee9435dd17 245 t4[1] = pMid2[1];
EricLew 0:3eee9435dd17 246 t4[2] = pMid2[2];
EricLew 0:3eee9435dd17 247 t4[3] = pMid2[3];
EricLew 0:3eee9435dd17 248
EricLew 0:3eee9435dd17 249 *p1++ = t1[0] + t2[0];
EricLew 0:3eee9435dd17 250 *p1++ = t1[1] + t2[1];
EricLew 0:3eee9435dd17 251 *p1++ = t1[2] + t2[2];
EricLew 0:3eee9435dd17 252 *p1++ = t1[3] + t2[3]; // col 1
EricLew 0:3eee9435dd17 253
EricLew 0:3eee9435dd17 254 t2[0] = t1[0] - t2[0];
EricLew 0:3eee9435dd17 255 t2[1] = t1[1] - t2[1];
EricLew 0:3eee9435dd17 256 t2[2] = t1[2] - t2[2];
EricLew 0:3eee9435dd17 257 t2[3] = t1[3] - t2[3]; // for col 2
EricLew 0:3eee9435dd17 258
EricLew 0:3eee9435dd17 259 *pMid1++ = t3[0] + t4[0];
EricLew 0:3eee9435dd17 260 *pMid1++ = t3[1] + t4[1];
EricLew 0:3eee9435dd17 261 *pMid1++ = t3[2] + t4[2];
EricLew 0:3eee9435dd17 262 *pMid1++ = t3[3] + t4[3]; // col 1
EricLew 0:3eee9435dd17 263
EricLew 0:3eee9435dd17 264 t4[0] = t4[0] - t3[0];
EricLew 0:3eee9435dd17 265 t4[1] = t4[1] - t3[1];
EricLew 0:3eee9435dd17 266 t4[2] = t4[2] - t3[2];
EricLew 0:3eee9435dd17 267 t4[3] = t4[3] - t3[3]; // for col 2
EricLew 0:3eee9435dd17 268
EricLew 0:3eee9435dd17 269 twR = *tw++;
EricLew 0:3eee9435dd17 270 twI = *tw++;
EricLew 0:3eee9435dd17 271
EricLew 0:3eee9435dd17 272 // multiply by twiddle factors
EricLew 0:3eee9435dd17 273 m0 = t2[0] * twR;
EricLew 0:3eee9435dd17 274 m1 = t2[1] * twI;
EricLew 0:3eee9435dd17 275 m2 = t2[1] * twR;
EricLew 0:3eee9435dd17 276 m3 = t2[0] * twI;
EricLew 0:3eee9435dd17 277
EricLew 0:3eee9435dd17 278 // R = R * Tr - I * Ti
EricLew 0:3eee9435dd17 279 *p2++ = m0 + m1;
EricLew 0:3eee9435dd17 280 // I = I * Tr + R * Ti
EricLew 0:3eee9435dd17 281 *p2++ = m2 - m3;
EricLew 0:3eee9435dd17 282
EricLew 0:3eee9435dd17 283 // use vertical symmetry
EricLew 0:3eee9435dd17 284 // 0.9988 - 0.0491i <==> -0.0491 - 0.9988i
EricLew 0:3eee9435dd17 285 m0 = t4[0] * twI;
EricLew 0:3eee9435dd17 286 m1 = t4[1] * twR;
EricLew 0:3eee9435dd17 287 m2 = t4[1] * twI;
EricLew 0:3eee9435dd17 288 m3 = t4[0] * twR;
EricLew 0:3eee9435dd17 289
EricLew 0:3eee9435dd17 290 *pMid2++ = m0 - m1;
EricLew 0:3eee9435dd17 291 *pMid2++ = m2 + m3;
EricLew 0:3eee9435dd17 292
EricLew 0:3eee9435dd17 293 twR = *tw++;
EricLew 0:3eee9435dd17 294 twI = *tw++;
EricLew 0:3eee9435dd17 295
EricLew 0:3eee9435dd17 296 m0 = t2[2] * twR;
EricLew 0:3eee9435dd17 297 m1 = t2[3] * twI;
EricLew 0:3eee9435dd17 298 m2 = t2[3] * twR;
EricLew 0:3eee9435dd17 299 m3 = t2[2] * twI;
EricLew 0:3eee9435dd17 300
EricLew 0:3eee9435dd17 301 *p2++ = m0 + m1;
EricLew 0:3eee9435dd17 302 *p2++ = m2 - m3;
EricLew 0:3eee9435dd17 303
EricLew 0:3eee9435dd17 304 m0 = t4[2] * twI;
EricLew 0:3eee9435dd17 305 m1 = t4[3] * twR;
EricLew 0:3eee9435dd17 306 m2 = t4[3] * twI;
EricLew 0:3eee9435dd17 307 m3 = t4[2] * twR;
EricLew 0:3eee9435dd17 308
EricLew 0:3eee9435dd17 309 *pMid2++ = m0 - m1;
EricLew 0:3eee9435dd17 310 *pMid2++ = m2 + m3;
EricLew 0:3eee9435dd17 311 }
EricLew 0:3eee9435dd17 312
EricLew 0:3eee9435dd17 313 // first col
EricLew 0:3eee9435dd17 314 arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 2u);
EricLew 0:3eee9435dd17 315 // second col
EricLew 0:3eee9435dd17 316 arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 2u);
EricLew 0:3eee9435dd17 317 }
EricLew 0:3eee9435dd17 318
EricLew 0:3eee9435dd17 319 void arm_cfft_radix8by4_f32( arm_cfft_instance_f32 * S, float32_t * p1)
EricLew 0:3eee9435dd17 320 {
EricLew 0:3eee9435dd17 321 uint32_t L = S->fftLen >> 1;
EricLew 0:3eee9435dd17 322 float32_t * pCol1, *pCol2, *pCol3, *pCol4, *pEnd1, *pEnd2, *pEnd3, *pEnd4;
EricLew 0:3eee9435dd17 323 const float32_t *tw2, *tw3, *tw4;
EricLew 0:3eee9435dd17 324 float32_t * p2 = p1 + L;
EricLew 0:3eee9435dd17 325 float32_t * p3 = p2 + L;
EricLew 0:3eee9435dd17 326 float32_t * p4 = p3 + L;
EricLew 0:3eee9435dd17 327 float32_t t2[4], t3[4], t4[4], twR, twI;
EricLew 0:3eee9435dd17 328 float32_t p1ap3_0, p1sp3_0, p1ap3_1, p1sp3_1;
EricLew 0:3eee9435dd17 329 float32_t m0, m1, m2, m3;
EricLew 0:3eee9435dd17 330 uint32_t l, twMod2, twMod3, twMod4;
EricLew 0:3eee9435dd17 331
EricLew 0:3eee9435dd17 332 pCol1 = p1; // points to real values by default
EricLew 0:3eee9435dd17 333 pCol2 = p2;
EricLew 0:3eee9435dd17 334 pCol3 = p3;
EricLew 0:3eee9435dd17 335 pCol4 = p4;
EricLew 0:3eee9435dd17 336 pEnd1 = p2 - 1; // points to imaginary values by default
EricLew 0:3eee9435dd17 337 pEnd2 = p3 - 1;
EricLew 0:3eee9435dd17 338 pEnd3 = p4 - 1;
EricLew 0:3eee9435dd17 339 pEnd4 = pEnd3 + L;
EricLew 0:3eee9435dd17 340
EricLew 0:3eee9435dd17 341 tw2 = tw3 = tw4 = (float32_t *) S->pTwiddle;
EricLew 0:3eee9435dd17 342
EricLew 0:3eee9435dd17 343 L >>= 1;
EricLew 0:3eee9435dd17 344
EricLew 0:3eee9435dd17 345 // do four dot Fourier transform
EricLew 0:3eee9435dd17 346
EricLew 0:3eee9435dd17 347 twMod2 = 2;
EricLew 0:3eee9435dd17 348 twMod3 = 4;
EricLew 0:3eee9435dd17 349 twMod4 = 6;
EricLew 0:3eee9435dd17 350
EricLew 0:3eee9435dd17 351 // TOP
EricLew 0:3eee9435dd17 352 p1ap3_0 = p1[0] + p3[0];
EricLew 0:3eee9435dd17 353 p1sp3_0 = p1[0] - p3[0];
EricLew 0:3eee9435dd17 354 p1ap3_1 = p1[1] + p3[1];
EricLew 0:3eee9435dd17 355 p1sp3_1 = p1[1] - p3[1];
EricLew 0:3eee9435dd17 356
EricLew 0:3eee9435dd17 357 // col 2
EricLew 0:3eee9435dd17 358 t2[0] = p1sp3_0 + p2[1] - p4[1];
EricLew 0:3eee9435dd17 359 t2[1] = p1sp3_1 - p2[0] + p4[0];
EricLew 0:3eee9435dd17 360 // col 3
EricLew 0:3eee9435dd17 361 t3[0] = p1ap3_0 - p2[0] - p4[0];
EricLew 0:3eee9435dd17 362 t3[1] = p1ap3_1 - p2[1] - p4[1];
EricLew 0:3eee9435dd17 363 // col 4
EricLew 0:3eee9435dd17 364 t4[0] = p1sp3_0 - p2[1] + p4[1];
EricLew 0:3eee9435dd17 365 t4[1] = p1sp3_1 + p2[0] - p4[0];
EricLew 0:3eee9435dd17 366 // col 1
EricLew 0:3eee9435dd17 367 *p1++ = p1ap3_0 + p2[0] + p4[0];
EricLew 0:3eee9435dd17 368 *p1++ = p1ap3_1 + p2[1] + p4[1];
EricLew 0:3eee9435dd17 369
EricLew 0:3eee9435dd17 370 // Twiddle factors are ones
EricLew 0:3eee9435dd17 371 *p2++ = t2[0];
EricLew 0:3eee9435dd17 372 *p2++ = t2[1];
EricLew 0:3eee9435dd17 373 *p3++ = t3[0];
EricLew 0:3eee9435dd17 374 *p3++ = t3[1];
EricLew 0:3eee9435dd17 375 *p4++ = t4[0];
EricLew 0:3eee9435dd17 376 *p4++ = t4[1];
EricLew 0:3eee9435dd17 377
EricLew 0:3eee9435dd17 378 tw2 += twMod2;
EricLew 0:3eee9435dd17 379 tw3 += twMod3;
EricLew 0:3eee9435dd17 380 tw4 += twMod4;
EricLew 0:3eee9435dd17 381
EricLew 0:3eee9435dd17 382 for (l = (L - 2) >> 1; l > 0; l-- )
EricLew 0:3eee9435dd17 383 {
EricLew 0:3eee9435dd17 384 // TOP
EricLew 0:3eee9435dd17 385 p1ap3_0 = p1[0] + p3[0];
EricLew 0:3eee9435dd17 386 p1sp3_0 = p1[0] - p3[0];
EricLew 0:3eee9435dd17 387 p1ap3_1 = p1[1] + p3[1];
EricLew 0:3eee9435dd17 388 p1sp3_1 = p1[1] - p3[1];
EricLew 0:3eee9435dd17 389 // col 2
EricLew 0:3eee9435dd17 390 t2[0] = p1sp3_0 + p2[1] - p4[1];
EricLew 0:3eee9435dd17 391 t2[1] = p1sp3_1 - p2[0] + p4[0];
EricLew 0:3eee9435dd17 392 // col 3
EricLew 0:3eee9435dd17 393 t3[0] = p1ap3_0 - p2[0] - p4[0];
EricLew 0:3eee9435dd17 394 t3[1] = p1ap3_1 - p2[1] - p4[1];
EricLew 0:3eee9435dd17 395 // col 4
EricLew 0:3eee9435dd17 396 t4[0] = p1sp3_0 - p2[1] + p4[1];
EricLew 0:3eee9435dd17 397 t4[1] = p1sp3_1 + p2[0] - p4[0];
EricLew 0:3eee9435dd17 398 // col 1 - top
EricLew 0:3eee9435dd17 399 *p1++ = p1ap3_0 + p2[0] + p4[0];
EricLew 0:3eee9435dd17 400 *p1++ = p1ap3_1 + p2[1] + p4[1];
EricLew 0:3eee9435dd17 401
EricLew 0:3eee9435dd17 402 // BOTTOM
EricLew 0:3eee9435dd17 403 p1ap3_1 = pEnd1[-1] + pEnd3[-1];
EricLew 0:3eee9435dd17 404 p1sp3_1 = pEnd1[-1] - pEnd3[-1];
EricLew 0:3eee9435dd17 405 p1ap3_0 = pEnd1[0] + pEnd3[0];
EricLew 0:3eee9435dd17 406 p1sp3_0 = pEnd1[0] - pEnd3[0];
EricLew 0:3eee9435dd17 407 // col 2
EricLew 0:3eee9435dd17 408 t2[2] = pEnd2[0] - pEnd4[0] + p1sp3_1;
EricLew 0:3eee9435dd17 409 t2[3] = pEnd1[0] - pEnd3[0] - pEnd2[-1] + pEnd4[-1];
EricLew 0:3eee9435dd17 410 // col 3
EricLew 0:3eee9435dd17 411 t3[2] = p1ap3_1 - pEnd2[-1] - pEnd4[-1];
EricLew 0:3eee9435dd17 412 t3[3] = p1ap3_0 - pEnd2[0] - pEnd4[0];
EricLew 0:3eee9435dd17 413 // col 4
EricLew 0:3eee9435dd17 414 t4[2] = pEnd2[0] - pEnd4[0] - p1sp3_1;
EricLew 0:3eee9435dd17 415 t4[3] = pEnd4[-1] - pEnd2[-1] - p1sp3_0;
EricLew 0:3eee9435dd17 416 // col 1 - Bottom
EricLew 0:3eee9435dd17 417 *pEnd1-- = p1ap3_0 + pEnd2[0] + pEnd4[0];
EricLew 0:3eee9435dd17 418 *pEnd1-- = p1ap3_1 + pEnd2[-1] + pEnd4[-1];
EricLew 0:3eee9435dd17 419
EricLew 0:3eee9435dd17 420 // COL 2
EricLew 0:3eee9435dd17 421 // read twiddle factors
EricLew 0:3eee9435dd17 422 twR = *tw2++;
EricLew 0:3eee9435dd17 423 twI = *tw2++;
EricLew 0:3eee9435dd17 424 // multiply by twiddle factors
EricLew 0:3eee9435dd17 425 // let Z1 = a + i(b), Z2 = c + i(d)
EricLew 0:3eee9435dd17 426 // => Z1 * Z2 = (a*c - b*d) + i(b*c + a*d)
EricLew 0:3eee9435dd17 427
EricLew 0:3eee9435dd17 428 // Top
EricLew 0:3eee9435dd17 429 m0 = t2[0] * twR;
EricLew 0:3eee9435dd17 430 m1 = t2[1] * twI;
EricLew 0:3eee9435dd17 431 m2 = t2[1] * twR;
EricLew 0:3eee9435dd17 432 m3 = t2[0] * twI;
EricLew 0:3eee9435dd17 433
EricLew 0:3eee9435dd17 434 *p2++ = m0 + m1;
EricLew 0:3eee9435dd17 435 *p2++ = m2 - m3;
EricLew 0:3eee9435dd17 436 // use vertical symmetry col 2
EricLew 0:3eee9435dd17 437 // 0.9997 - 0.0245i <==> 0.0245 - 0.9997i
EricLew 0:3eee9435dd17 438 // Bottom
EricLew 0:3eee9435dd17 439 m0 = t2[3] * twI;
EricLew 0:3eee9435dd17 440 m1 = t2[2] * twR;
EricLew 0:3eee9435dd17 441 m2 = t2[2] * twI;
EricLew 0:3eee9435dd17 442 m3 = t2[3] * twR;
EricLew 0:3eee9435dd17 443
EricLew 0:3eee9435dd17 444 *pEnd2-- = m0 - m1;
EricLew 0:3eee9435dd17 445 *pEnd2-- = m2 + m3;
EricLew 0:3eee9435dd17 446
EricLew 0:3eee9435dd17 447 // COL 3
EricLew 0:3eee9435dd17 448 twR = tw3[0];
EricLew 0:3eee9435dd17 449 twI = tw3[1];
EricLew 0:3eee9435dd17 450 tw3 += twMod3;
EricLew 0:3eee9435dd17 451 // Top
EricLew 0:3eee9435dd17 452 m0 = t3[0] * twR;
EricLew 0:3eee9435dd17 453 m1 = t3[1] * twI;
EricLew 0:3eee9435dd17 454 m2 = t3[1] * twR;
EricLew 0:3eee9435dd17 455 m3 = t3[0] * twI;
EricLew 0:3eee9435dd17 456
EricLew 0:3eee9435dd17 457 *p3++ = m0 + m1;
EricLew 0:3eee9435dd17 458 *p3++ = m2 - m3;
EricLew 0:3eee9435dd17 459 // use vertical symmetry col 3
EricLew 0:3eee9435dd17 460 // 0.9988 - 0.0491i <==> -0.9988 - 0.0491i
EricLew 0:3eee9435dd17 461 // Bottom
EricLew 0:3eee9435dd17 462 m0 = -t3[3] * twR;
EricLew 0:3eee9435dd17 463 m1 = t3[2] * twI;
EricLew 0:3eee9435dd17 464 m2 = t3[2] * twR;
EricLew 0:3eee9435dd17 465 m3 = t3[3] * twI;
EricLew 0:3eee9435dd17 466
EricLew 0:3eee9435dd17 467 *pEnd3-- = m0 - m1;
EricLew 0:3eee9435dd17 468 *pEnd3-- = m3 - m2;
EricLew 0:3eee9435dd17 469
EricLew 0:3eee9435dd17 470 // COL 4
EricLew 0:3eee9435dd17 471 twR = tw4[0];
EricLew 0:3eee9435dd17 472 twI = tw4[1];
EricLew 0:3eee9435dd17 473 tw4 += twMod4;
EricLew 0:3eee9435dd17 474 // Top
EricLew 0:3eee9435dd17 475 m0 = t4[0] * twR;
EricLew 0:3eee9435dd17 476 m1 = t4[1] * twI;
EricLew 0:3eee9435dd17 477 m2 = t4[1] * twR;
EricLew 0:3eee9435dd17 478 m3 = t4[0] * twI;
EricLew 0:3eee9435dd17 479
EricLew 0:3eee9435dd17 480 *p4++ = m0 + m1;
EricLew 0:3eee9435dd17 481 *p4++ = m2 - m3;
EricLew 0:3eee9435dd17 482 // use vertical symmetry col 4
EricLew 0:3eee9435dd17 483 // 0.9973 - 0.0736i <==> -0.0736 + 0.9973i
EricLew 0:3eee9435dd17 484 // Bottom
EricLew 0:3eee9435dd17 485 m0 = t4[3] * twI;
EricLew 0:3eee9435dd17 486 m1 = t4[2] * twR;
EricLew 0:3eee9435dd17 487 m2 = t4[2] * twI;
EricLew 0:3eee9435dd17 488 m3 = t4[3] * twR;
EricLew 0:3eee9435dd17 489
EricLew 0:3eee9435dd17 490 *pEnd4-- = m0 - m1;
EricLew 0:3eee9435dd17 491 *pEnd4-- = m2 + m3;
EricLew 0:3eee9435dd17 492 }
EricLew 0:3eee9435dd17 493
EricLew 0:3eee9435dd17 494 //MIDDLE
EricLew 0:3eee9435dd17 495 // Twiddle factors are
EricLew 0:3eee9435dd17 496 // 1.0000 0.7071-0.7071i -1.0000i -0.7071-0.7071i
EricLew 0:3eee9435dd17 497 p1ap3_0 = p1[0] + p3[0];
EricLew 0:3eee9435dd17 498 p1sp3_0 = p1[0] - p3[0];
EricLew 0:3eee9435dd17 499 p1ap3_1 = p1[1] + p3[1];
EricLew 0:3eee9435dd17 500 p1sp3_1 = p1[1] - p3[1];
EricLew 0:3eee9435dd17 501
EricLew 0:3eee9435dd17 502 // col 2
EricLew 0:3eee9435dd17 503 t2[0] = p1sp3_0 + p2[1] - p4[1];
EricLew 0:3eee9435dd17 504 t2[1] = p1sp3_1 - p2[0] + p4[0];
EricLew 0:3eee9435dd17 505 // col 3
EricLew 0:3eee9435dd17 506 t3[0] = p1ap3_0 - p2[0] - p4[0];
EricLew 0:3eee9435dd17 507 t3[1] = p1ap3_1 - p2[1] - p4[1];
EricLew 0:3eee9435dd17 508 // col 4
EricLew 0:3eee9435dd17 509 t4[0] = p1sp3_0 - p2[1] + p4[1];
EricLew 0:3eee9435dd17 510 t4[1] = p1sp3_1 + p2[0] - p4[0];
EricLew 0:3eee9435dd17 511 // col 1 - Top
EricLew 0:3eee9435dd17 512 *p1++ = p1ap3_0 + p2[0] + p4[0];
EricLew 0:3eee9435dd17 513 *p1++ = p1ap3_1 + p2[1] + p4[1];
EricLew 0:3eee9435dd17 514
EricLew 0:3eee9435dd17 515 // COL 2
EricLew 0:3eee9435dd17 516 twR = tw2[0];
EricLew 0:3eee9435dd17 517 twI = tw2[1];
EricLew 0:3eee9435dd17 518
EricLew 0:3eee9435dd17 519 m0 = t2[0] * twR;
EricLew 0:3eee9435dd17 520 m1 = t2[1] * twI;
EricLew 0:3eee9435dd17 521 m2 = t2[1] * twR;
EricLew 0:3eee9435dd17 522 m3 = t2[0] * twI;
EricLew 0:3eee9435dd17 523
EricLew 0:3eee9435dd17 524 *p2++ = m0 + m1;
EricLew 0:3eee9435dd17 525 *p2++ = m2 - m3;
EricLew 0:3eee9435dd17 526 // COL 3
EricLew 0:3eee9435dd17 527 twR = tw3[0];
EricLew 0:3eee9435dd17 528 twI = tw3[1];
EricLew 0:3eee9435dd17 529
EricLew 0:3eee9435dd17 530 m0 = t3[0] * twR;
EricLew 0:3eee9435dd17 531 m1 = t3[1] * twI;
EricLew 0:3eee9435dd17 532 m2 = t3[1] * twR;
EricLew 0:3eee9435dd17 533 m3 = t3[0] * twI;
EricLew 0:3eee9435dd17 534
EricLew 0:3eee9435dd17 535 *p3++ = m0 + m1;
EricLew 0:3eee9435dd17 536 *p3++ = m2 - m3;
EricLew 0:3eee9435dd17 537 // COL 4
EricLew 0:3eee9435dd17 538 twR = tw4[0];
EricLew 0:3eee9435dd17 539 twI = tw4[1];
EricLew 0:3eee9435dd17 540
EricLew 0:3eee9435dd17 541 m0 = t4[0] * twR;
EricLew 0:3eee9435dd17 542 m1 = t4[1] * twI;
EricLew 0:3eee9435dd17 543 m2 = t4[1] * twR;
EricLew 0:3eee9435dd17 544 m3 = t4[0] * twI;
EricLew 0:3eee9435dd17 545
EricLew 0:3eee9435dd17 546 *p4++ = m0 + m1;
EricLew 0:3eee9435dd17 547 *p4++ = m2 - m3;
EricLew 0:3eee9435dd17 548
EricLew 0:3eee9435dd17 549 // first col
EricLew 0:3eee9435dd17 550 arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 4u);
EricLew 0:3eee9435dd17 551 // second col
EricLew 0:3eee9435dd17 552 arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 4u);
EricLew 0:3eee9435dd17 553 // third col
EricLew 0:3eee9435dd17 554 arm_radix8_butterfly_f32( pCol3, L, (float32_t *) S->pTwiddle, 4u);
EricLew 0:3eee9435dd17 555 // fourth col
EricLew 0:3eee9435dd17 556 arm_radix8_butterfly_f32( pCol4, L, (float32_t *) S->pTwiddle, 4u);
EricLew 0:3eee9435dd17 557 }
EricLew 0:3eee9435dd17 558
EricLew 0:3eee9435dd17 559 /**
EricLew 0:3eee9435dd17 560 * @addtogroup ComplexFFT
EricLew 0:3eee9435dd17 561 * @{
EricLew 0:3eee9435dd17 562 */
EricLew 0:3eee9435dd17 563
EricLew 0:3eee9435dd17 564 /**
EricLew 0:3eee9435dd17 565 * @details
EricLew 0:3eee9435dd17 566 * @brief Processing function for the floating-point complex FFT.
EricLew 0:3eee9435dd17 567 * @param[in] *S points to an instance of the floating-point CFFT structure.
EricLew 0:3eee9435dd17 568 * @param[in, out] *p1 points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
EricLew 0:3eee9435dd17 569 * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
EricLew 0:3eee9435dd17 570 * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
EricLew 0:3eee9435dd17 571 * @return none.
EricLew 0:3eee9435dd17 572 */
EricLew 0:3eee9435dd17 573
EricLew 0:3eee9435dd17 574 void arm_cfft_f32(
EricLew 0:3eee9435dd17 575 const arm_cfft_instance_f32 * S,
EricLew 0:3eee9435dd17 576 float32_t * p1,
EricLew 0:3eee9435dd17 577 uint8_t ifftFlag,
EricLew 0:3eee9435dd17 578 uint8_t bitReverseFlag)
EricLew 0:3eee9435dd17 579 {
EricLew 0:3eee9435dd17 580 uint32_t L = S->fftLen, l;
EricLew 0:3eee9435dd17 581 float32_t invL, * pSrc;
EricLew 0:3eee9435dd17 582
EricLew 0:3eee9435dd17 583 if(ifftFlag == 1u)
EricLew 0:3eee9435dd17 584 {
EricLew 0:3eee9435dd17 585 /* Conjugate input data */
EricLew 0:3eee9435dd17 586 pSrc = p1 + 1;
EricLew 0:3eee9435dd17 587 for(l=0; l<L; l++)
EricLew 0:3eee9435dd17 588 {
EricLew 0:3eee9435dd17 589 *pSrc = -*pSrc;
EricLew 0:3eee9435dd17 590 pSrc += 2;
EricLew 0:3eee9435dd17 591 }
EricLew 0:3eee9435dd17 592 }
EricLew 0:3eee9435dd17 593
EricLew 0:3eee9435dd17 594 switch (L)
EricLew 0:3eee9435dd17 595 {
EricLew 0:3eee9435dd17 596 case 16:
EricLew 0:3eee9435dd17 597 case 128:
EricLew 0:3eee9435dd17 598 case 1024:
EricLew 0:3eee9435dd17 599 arm_cfft_radix8by2_f32 ( (arm_cfft_instance_f32 *) S, p1);
EricLew 0:3eee9435dd17 600 break;
EricLew 0:3eee9435dd17 601 case 32:
EricLew 0:3eee9435dd17 602 case 256:
EricLew 0:3eee9435dd17 603 case 2048:
EricLew 0:3eee9435dd17 604 arm_cfft_radix8by4_f32 ( (arm_cfft_instance_f32 *) S, p1);
EricLew 0:3eee9435dd17 605 break;
EricLew 0:3eee9435dd17 606 case 64:
EricLew 0:3eee9435dd17 607 case 512:
EricLew 0:3eee9435dd17 608 case 4096:
EricLew 0:3eee9435dd17 609 arm_radix8_butterfly_f32( p1, L, (float32_t *) S->pTwiddle, 1);
EricLew 0:3eee9435dd17 610 break;
EricLew 0:3eee9435dd17 611 }
EricLew 0:3eee9435dd17 612
EricLew 0:3eee9435dd17 613 // if( bitReverseFlag )
EricLew 0:3eee9435dd17 614 // arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
EricLew 0:3eee9435dd17 615
EricLew 0:3eee9435dd17 616 if(ifftFlag == 1u)
EricLew 0:3eee9435dd17 617 {
EricLew 0:3eee9435dd17 618 invL = 1.0f/(float32_t)L;
EricLew 0:3eee9435dd17 619 /* Conjugate and scale output data */
EricLew 0:3eee9435dd17 620 pSrc = p1;
EricLew 0:3eee9435dd17 621 for(l=0; l<L; l++)
EricLew 0:3eee9435dd17 622 {
EricLew 0:3eee9435dd17 623 *pSrc++ *= invL ;
EricLew 0:3eee9435dd17 624 *pSrc = -(*pSrc) * invL;
EricLew 0:3eee9435dd17 625 pSrc++;
EricLew 0:3eee9435dd17 626 }
EricLew 0:3eee9435dd17 627 }
EricLew 0:3eee9435dd17 628 }
EricLew 0:3eee9435dd17 629
EricLew 0:3eee9435dd17 630 /**
EricLew 0:3eee9435dd17 631 * @} end of ComplexFFT group
EricLew 0:3eee9435dd17 632 */