CMSIS DSP Software Library: arm_dct4_f32.c Source File

- Main Page
- Modules
- Data Structures
- Files
- Examples

- File List
- Globals

# arm_dct4_f32.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------
    00002 * Copyright (C) 2010 ARM Limited. All rights reserved.
    00003 *
    00004 * $Date:        15. July 2011
    00005 * $Revision:    V1.0.10
    00006 *
    00007 * Project:      CMSIS DSP Library
    00008 * Title:        arm_dct4_f32.c
    00009 *
    00010 * Description:  Processing function of DCT4 & IDCT4 F32.
    00011 *
    00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
    00013 *
    00014 * Version 1.0.10 2011/7/15
    00015 *    Big Endian support added and Merged M0 and M3/M4 Source code.
    00016 *
    00017 * Version 1.0.3 2010/11/29
    00018 *    Re-organized the CMSIS folders and updated documentation.
    00019 *
    00020 * Version 1.0.2 2010/11/11
    00021 *    Documentation updated.
    00022 *
    00023 * Version 1.0.1 2010/10/05
    00024 *    Production release and review comments incorporated.
    00025 *
    00026 * Version 1.0.0 2010/09/20
    00027 *    Production release and review comments incorporated.
    00028 * -------------------------------------------------------------------- */
    00029
    00030 #include "arm_math.h"
    00031
    00126 void arm_dct4_f32(
    00127   const arm_dct4_instance_f32 * S,
    00128   float32_t * pState,
    00129   float32_t * pInlineBuffer)
    00130 {
    00131   uint32_t i;                                    /* Loop counter */
    00132   float32_t *weights = S->pTwiddle;              /* Pointer to the Weights table */
    00133   float32_t *cosFact = S->pCosFactor;            /* Pointer to the cos factors table */
    00134   float32_t *pS1, *pS2, *pbuff;                  /* Temporary pointers for input buffer and pState buffer */
    00135   float32_t in;                                  /* Temporary variable */
    00136
    00137
    00138   /* DCT4 computation involves DCT2 (which is calculated using RFFT)
    00139    * along with some pre-processing and post-processing.
    00140    * Computational procedure is explained as follows:
    00141    * (a) Pre-processing involves multiplying input with cos factor,
    00142    *     r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n))
    00143    *              where,
    00144    *                 r(n) -- output of preprocessing
    00145    *                 u(n) -- input to preprocessing(actual Source buffer)
    00146    * (b) Calculation of DCT2 using FFT is divided into three steps:
    00147    *                  Step1: Re-ordering of even and odd elements of input.
    00148    *                  Step2: Calculating FFT of the re-ordered input.
    00149    *                  Step3: Taking the real part of the product of FFT output and weights.
    00150    * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation:
    00151    *                   Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
    00152    *                        where,
    00153    *                           Y4 -- DCT4 output,   Y2 -- DCT2 output
    00154    * (d) Multiplying the output with the normalizing factor sqrt(2/N).
    00155    */
    00156
    00157         /*-------- Pre-processing ------------*/
    00158   /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */
    00159   arm_scale_f32(pInlineBuffer, 2.0f, pInlineBuffer, S->N);
    00160   arm_mult_f32(pInlineBuffer, cosFact, pInlineBuffer, S->N);
    00161
    00162   /* ----------------------------------------------------------------
    00163    * Step1: Re-ordering of even and odd elements as,
    00164    *             pState[i] =  pInlineBuffer[2*i] and
    00165    *             pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2
    00166    ---------------------------------------------------------------------*/
    00167
    00168   /* pS1 initialized to pState */
    00169   pS1 = pState;
    00170
    00171   /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */
    00172   pS2 = pState + (S->N - 1u);
    00173
    00174   /* pbuff initialized to input buffer */
    00175   pbuff = pInlineBuffer;
    00176
    00177 #ifndef ARM_MATH_CM0
    00178
    00179   /* Run the below code for Cortex-M4 and Cortex-M3 */
    00180
    00181   /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */
    00182   i = (uint32_t) S->Nby2 >> 2u;
    00183
    00184   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.
    00185    ** a second loop below computes the remaining 1 to 3 samples. */
    00186   do
    00187   {
    00188     /* Re-ordering of even and odd elements */
    00189     /* pState[i] =  pInlineBuffer[2*i] */
    00190     *pS1++ = *pbuff++;
    00191     /* pState[N-i-1] = pInlineBuffer[2*i+1] */
    00192     *pS2-- = *pbuff++;
    00193
    00194     *pS1++ = *pbuff++;
    00195     *pS2-- = *pbuff++;
    00196
    00197     *pS1++ = *pbuff++;
    00198     *pS2-- = *pbuff++;
    00199
    00200     *pS1++ = *pbuff++;
    00201     *pS2-- = *pbuff++;
    00202
    00203     /* Decrement the loop counter */
    00204     i--;
    00205   } while(i > 0u);
    00206
    00207   /* pbuff initialized to input buffer */
    00208   pbuff = pInlineBuffer;
    00209
    00210   /* pS1 initialized to pState */
    00211   pS1 = pState;
    00212
    00213   /* Initializing the loop counter to N/4 instead of N for loop unrolling */
    00214   i = (uint32_t) S->N >> 2u;
    00215
    00216   /* Processing with loop unrolling 4 times as N is always multiple of 4.
    00217    * Compute 4 outputs at a time */
    00218   do
    00219   {
    00220     /* Writing the re-ordered output back to inplace input buffer */
    00221     *pbuff++ = *pS1++;
    00222     *pbuff++ = *pS1++;
    00223     *pbuff++ = *pS1++;
    00224     *pbuff++ = *pS1++;
    00225
    00226     /* Decrement the loop counter */
    00227     i--;
    00228   } while(i > 0u);
    00229
    00230
    00231   /* ---------------------------------------------------------
    00232    *     Step2: Calculate RFFT for N-point input
    00233    * ---------------------------------------------------------- */
    00234   /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
    00235   arm_rfft_f32(S->pRfft, pInlineBuffer, pState);
    00236
    00237         /*----------------------------------------------------------------------
    00238      *  Step3: Multiply the FFT output with the weights.
    00239      *----------------------------------------------------------------------*/
    00240   arm_cmplx_mult_cmplx_f32(pState, weights, pState, S->N);
    00241
    00242   /* ----------- Post-processing ---------- */
    00243   /* DCT-IV can be obtained from DCT-II by the equation,
    00244    *       Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
    00245    *       Hence, Y4(0) = Y2(0)/2  */
    00246   /* Getting only real part from the output and Converting to DCT-IV */
    00247
    00248   /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */
    00249   i = ((uint32_t) S->N - 1u) >> 2u;
    00250
    00251   /* pbuff initialized to input buffer. */
    00252   pbuff = pInlineBuffer;
    00253
    00254   /* pS1 initialized to pState */
    00255   pS1 = pState;
    00256
    00257   /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
    00258   in = *pS1++ * (float32_t) 0.5;
    00259   /* input buffer acts as inplace, so output values are stored in the input itself. */
    00260   *pbuff++ = in;
    00261
    00262   /* pState pointer is incremented twice as the real values are located alternatively in the array */
    00263   pS1++;
    00264
    00265   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.
    00266    ** a second loop below computes the remaining 1 to 3 samples. */
    00267   do
    00268   {
    00269     /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
    00270     /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
    00271     in = *pS1++ - in;
    00272     *pbuff++ = in;
    00273     /* points to the next real value */
    00274     pS1++;
    00275
    00276     in = *pS1++ - in;
    00277     *pbuff++ = in;
    00278     pS1++;
    00279
    00280     in = *pS1++ - in;
    00281     *pbuff++ = in;
    00282     pS1++;
    00283
    00284     in = *pS1++ - in;
    00285     *pbuff++ = in;
    00286     pS1++;
    00287
    00288     /* Decrement the loop counter */
    00289     i--;
    00290   } while(i > 0u);
    00291
    00292   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
    00293    ** No loop unrolling is used. */
    00294   i = ((uint32_t) S->N - 1u) % 0x4u;
    00295
    00296   while(i > 0u)
    00297   {
    00298     /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
    00299     /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
    00300     in = *pS1++ - in;
    00301     *pbuff++ = in;
    00302     /* points to the next real value */
    00303     pS1++;
    00304
    00305     /* Decrement the loop counter */
    00306     i--;
    00307   }
    00308
    00309
    00310         /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
    00311
    00312   /* Initializing the loop counter to N/4 instead of N for loop unrolling */
    00313   i = (uint32_t) S->N >> 2u;
    00314
    00315   /* pbuff initialized to the pInlineBuffer(now contains the output values) */
    00316   pbuff = pInlineBuffer;
    00317
    00318   /* Processing with loop unrolling 4 times as N is always multiple of 4.  Compute 4 outputs at a time */
    00319   do
    00320   {
    00321     /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
    00322     in = *pbuff;
    00323     *pbuff++ = in * S->normalize;
    00324
    00325     in = *pbuff;
    00326     *pbuff++ = in * S->normalize;
    00327
    00328     in = *pbuff;
    00329     *pbuff++ = in * S->normalize;
    00330
    00331     in = *pbuff;
    00332     *pbuff++ = in * S->normalize;
    00333
    00334     /* Decrement the loop counter */
    00335     i--;
    00336   } while(i > 0u);
    00337
    00338
    00339 #else
    00340
    00341   /* Run the below code for Cortex-M0 */
    00342
    00343   /* Initializing the loop counter to N/2 */
    00344   i = (uint32_t) S->Nby2;
    00345
    00346   do
    00347   {
    00348     /* Re-ordering of even and odd elements */
    00349     /* pState[i] =  pInlineBuffer[2*i] */
    00350     *pS1++ = *pbuff++;
    00351     /* pState[N-i-1] = pInlineBuffer[2*i+1] */
    00352     *pS2-- = *pbuff++;
    00353
    00354     /* Decrement the loop counter */
    00355     i--;
    00356   } while(i > 0u);
    00357
    00358   /* pbuff initialized to input buffer */
    00359   pbuff = pInlineBuffer;
    00360
    00361   /* pS1 initialized to pState */
    00362   pS1 = pState;
    00363
    00364   /* Initializing the loop counter */
    00365   i = (uint32_t) S->N;
    00366
    00367   do
    00368   {
    00369     /* Writing the re-ordered output back to inplace input buffer */
    00370     *pbuff++ = *pS1++;
    00371
    00372     /* Decrement the loop counter */
    00373     i--;
    00374   } while(i > 0u);
    00375
    00376
    00377   /* ---------------------------------------------------------
    00378    *     Step2: Calculate RFFT for N-point input
    00379    * ---------------------------------------------------------- */
    00380   /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
    00381   arm_rfft_f32(S->pRfft, pInlineBuffer, pState);
    00382
    00383         /*----------------------------------------------------------------------
    00384      *  Step3: Multiply the FFT output with the weights.
    00385      *----------------------------------------------------------------------*/
    00386   arm_cmplx_mult_cmplx_f32(pState, weights, pState, S->N);
    00387
    00388   /* ----------- Post-processing ---------- */
    00389   /* DCT-IV can be obtained from DCT-II by the equation,
    00390    *       Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
    00391    *       Hence, Y4(0) = Y2(0)/2  */
    00392   /* Getting only real part from the output and Converting to DCT-IV */
    00393
    00394   /* pbuff initialized to input buffer. */
    00395   pbuff = pInlineBuffer;
    00396
    00397   /* pS1 initialized to pState */
    00398   pS1 = pState;
    00399
    00400   /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
    00401   in = *pS1++ * (float32_t) 0.5;
    00402   /* input buffer acts as inplace, so output values are stored in the input itself. */
    00403   *pbuff++ = in;
    00404
    00405   /* pState pointer is incremented twice as the real values are located alternatively in the array */
    00406   pS1++;
    00407
    00408   /* Initializing the loop counter */
    00409   i = ((uint32_t) S->N - 1u);
    00410
    00411   do
    00412   {
    00413     /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
    00414     /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
    00415     in = *pS1++ - in;
    00416     *pbuff++ = in;
    00417     /* points to the next real value */
    00418     pS1++;
    00419
    00420
    00421     /* Decrement the loop counter */
    00422     i--;
    00423   } while(i > 0u);
    00424
    00425
    00426         /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
    00427
    00428   /* Initializing the loop counter */
    00429   i = (uint32_t) S->N;
    00430
    00431   /* pbuff initialized to the pInlineBuffer(now contains the output values) */
    00432   pbuff = pInlineBuffer;
    00433
    00434   do
    00435   {
    00436     /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
    00437     in = *pbuff;
    00438     *pbuff++ = in * S->normalize;
    00439
    00440     /* Decrement the loop counter */
    00441     i--;
    00442   } while(i > 0u);
    00443
    00444 #endif /* #ifndef ARM_MATH_CM0 */
    00445
    00446 }
    00447

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines