- 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:        29. November 2010
    00005 * $Revision:    V1.0.3
    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
    00013 *
    00014 * Version 1.0.3 2010/11/29
    00015 *    Re-organized the CMSIS folders and updated documentation.
    00016 *
    00017 * Version 1.0.2 2010/11/11
    00018 *    Documentation updated.
    00019 *
    00020 * Version 1.0.1 2010/10/05
    00021 *    Production release and review comments incorporated.
    00022 *
    00023 * Version 1.0.0 2010/09/20
    00024 *    Production release and review comments incorporated.
    00025 * -------------------------------------------------------------------- */
    00026
    00027 #include "arm_math.h"
    00028
    00123 void arm_dct4_f32(
    00124   const arm_dct4_instance_f32 * S,
    00125   float32_t * pState,
    00126   float32_t * pInlineBuffer)
    00127 {
    00128   uint32_t i;                                    /* Loop counter */
    00129   float32_t *weights = S->pTwiddle;              /* Pointer to the Weights table */
    00130   float32_t *cosFact = S->pCosFactor;            /* Pointer to the cos factors table */
    00131   float32_t *pS1, *pS2, *pbuff;                  /* Temporary pointers for input buffer and pState buffer */
    00132   float32_t in;                                  /* Temporary variable */
    00133
    00134
    00135   /* DCT4 computation involves DCT2 (which is calculated using RFFT)
    00136    * along with some pre-processing and post-processing.
    00137    * Computational procedure is explained as follows:
    00138    * (a) Pre-processing involves multiplying input with cos factor,
    00139    *     r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n))
    00140    *              where,
    00141    *                 r(n) -- output of preprocessing
    00142    *                 u(n) -- input to preprocessing(actual Source buffer)
    00143    * (b) Calculation of DCT2 using FFT is divided into three steps:
    00144    *                  Step1: Re-ordering of even and odd elements of input.
    00145    *                  Step2: Calculating FFT of the re-ordered input.
    00146    *                  Step3: Taking the real part of the product of FFT output and weights.
    00147    * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation:
    00148    *                   Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
    00149    *                        where,
    00150    *                           Y4 -- DCT4 output,   Y2 -- DCT2 output
    00151    * (d) Multiplying the output with the normalizing factor sqrt(2/N).
    00152    */
    00153
    00154         /*-------- Pre-processing ------------*/
    00155   /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */
    00156   arm_scale_f32(pInlineBuffer, 2.0f, pInlineBuffer, S->N);
    00157   arm_mult_f32(pInlineBuffer, cosFact, pInlineBuffer, S->N);
    00158
    00159   /* ----------------------------------------------------------------
    00160    * Step1: Re-ordering of even and odd elements as,
    00161    *             pState[i] =  pInlineBuffer[2*i] and
    00162    *             pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2
    00163    ---------------------------------------------------------------------*/
    00164
    00165   /* pS1 initialized to pState */
    00166   pS1 = pState;
    00167
    00168   /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */
    00169   pS2 = pState + (S->N - 1u);
    00170
    00171   /* pbuff initialized to input buffer */
    00172   pbuff = pInlineBuffer;
    00173
    00174   /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */
    00175   i = (uint32_t) S->Nby2 >> 2u;
    00176
    00177   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.
    00178    ** a second loop below computes the remaining 1 to 3 samples. */
    00179   do
    00180   {
    00181     /* Re-ordering of even and odd elements */
    00182     /* pState[i] =  pInlineBuffer[2*i] */
    00183     *pS1++ = *pbuff++;
    00184     /* pState[N-i-1] = pInlineBuffer[2*i+1] */
    00185     *pS2-- = *pbuff++;
    00186
    00187     *pS1++ = *pbuff++;
    00188     *pS2-- = *pbuff++;
    00189
    00190     *pS1++ = *pbuff++;
    00191     *pS2-- = *pbuff++;
    00192
    00193     *pS1++ = *pbuff++;
    00194     *pS2-- = *pbuff++;
    00195
    00196     /* Decrement the loop counter */
    00197     i--;
    00198   } while(i > 0u);
    00199
    00200   /* pbuff initialized to input buffer */
    00201   pbuff = pInlineBuffer;
    00202
    00203   /* pS1 initialized to pState */
    00204   pS1 = pState;
    00205
    00206   /* Initializing the loop counter to N/4 instead of N for loop unrolling */
    00207   i = (uint32_t) S->N >> 2u;
    00208
    00209   /* Processing with loop unrolling 4 times as N is always multiple of 4.
    00210    * Compute 4 outputs at a time */
    00211   do
    00212   {
    00213     /* Writing the re-ordered output back to inplace input buffer */
    00214     *pbuff++ = *pS1++;
    00215     *pbuff++ = *pS1++;
    00216     *pbuff++ = *pS1++;
    00217     *pbuff++ = *pS1++;
    00218
    00219     /* Decrement the loop counter */
    00220     i--;
    00221   } while(i > 0u);
    00222
    00223
    00224   /* ---------------------------------------------------------
    00225    *     Step2: Calculate RFFT for N-point input
    00226    * ---------------------------------------------------------- */
    00227   /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
    00228   arm_rfft_f32(S->pRfft, pInlineBuffer, pState);
    00229
    00230         /*----------------------------------------------------------------------
    00231      *  Step3: Multiply the FFT output with the weights.
    00232      *----------------------------------------------------------------------*/
    00233   arm_cmplx_mult_cmplx_f32(pState, weights, pState, S->N);
    00234
    00235   /* ----------- Post-processing ---------- */
    00236   /* DCT-IV can be obtained from DCT-II by the equation,
    00237    *       Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
    00238    *       Hence, Y4(0) = Y2(0)/2  */
    00239   /* Getting only real part from the output and Converting to DCT-IV */
    00240
    00241   /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */
    00242   i = ((uint32_t) S->N - 1u) >> 2u;
    00243
    00244   /* pbuff initialized to input buffer. */
    00245   pbuff = pInlineBuffer;
    00246
    00247   /* pS1 initialized to pState */
    00248   pS1 = pState;
    00249
    00250   /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
    00251   in = *pS1++ * (float32_t) 0.5;
    00252   /* input buffer acts as inplace, so output values are stored in the input itself. */
    00253   *pbuff++ = in;
    00254
    00255   /* pState pointer is incremented twice as the real values are located alternatively in the array */
    00256   pS1++;
    00257
    00258   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.
    00259    ** a second loop below computes the remaining 1 to 3 samples. */
    00260   do
    00261   {
    00262     /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
    00263     /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
    00264     in = *pS1++ - in;
    00265     *pbuff++ = in;
    00266     /* points to the next real value */
    00267     pS1++;
    00268
    00269     in = *pS1++ - in;
    00270     *pbuff++ = in;
    00271     pS1++;
    00272
    00273     in = *pS1++ - in;
    00274     *pbuff++ = in;
    00275     pS1++;
    00276
    00277     in = *pS1++ - in;
    00278     *pbuff++ = in;
    00279     pS1++;
    00280
    00281     /* Decrement the loop counter */
    00282     i--;
    00283   } while(i > 0u);
    00284
    00285   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
    00286    ** No loop unrolling is used. */
    00287   i = ((uint32_t) S->N - 1u) % 0x4u;
    00288
    00289   while(i > 0u)
    00290   {
    00291     /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
    00292     /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
    00293     in = *pS1++ - in;
    00294     *pbuff++ = in;
    00295     /* points to the next real value */
    00296     pS1++;
    00297
    00298     /* Decrement the loop counter */
    00299     i--;
    00300   }
    00301
    00302
    00303         /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
    00304
    00305   /* Initializing the loop counter to N/4 instead of N for loop unrolling */
    00306   i = (uint32_t) S->N >> 2u;
    00307
    00308   /* pbuff initialized to the pInlineBuffer(now contains the output values) */
    00309   pbuff = pInlineBuffer;
    00310
    00311   /* Processing with loop unrolling 4 times as N is always multiple of 4.  Compute 4 outputs at a time */
    00312   do
    00313   {
    00314     /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
    00315     in = *pbuff;
    00316     *pbuff++ = in * S->normalize;
    00317
    00318     in = *pbuff;
    00319     *pbuff++ = in * S->normalize;
    00320
    00321     in = *pbuff;
    00322     *pbuff++ = in * S->normalize;
    00323
    00324     in = *pbuff;
    00325     *pbuff++ = in * S->normalize;
    00326
    00327     /* Decrement the loop counter */
    00328     i--;
    00329   } while(i > 0u);
    00330
    00331 }
    00332

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines