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

- File List
- Globals

# arm_biquad_cascade_df1_32x64_q31.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_biquad_cascade_df1_32x64_q31.c
    00009 *
    00010 * Description:  High precision Q31 Biquad cascade filter processing function
    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 * Version 0.0.7  2010/06/10
    00027 *    Misra-C changes done
    00028 * -------------------------------------------------------------------- */
    00029
    00030 #include "arm_math.h"
    00031
    00173 void arm_biquad_cas_df1_32x64_q31(
    00174   const arm_biquad_cas_df1_32x64_ins_q31 * S,
    00175   q31_t * pSrc,
    00176   q31_t * pDst,
    00177   uint32_t blockSize)
    00178 {
    00179   q31_t *pIn = pSrc;                             /*  input pointer initialization  */
    00180   q31_t *pOut = pDst;                            /*  output pointer initialization */
    00181   q63_t *pState = S->pState;                     /*  state pointer initialization  */
    00182   q31_t *pCoeffs = S->pCoeffs;                   /*  coeff pointer initialization  */
    00183   q63_t acc;                                     /*  accumulator                   */
    00184   q63_t Xn1, Xn2, Yn1, Yn2;                      /*  Filter state variables        */
    00185   q31_t b0, b1, b2, a1, a2;                      /*  Filter coefficients           */
    00186   q63_t Xn;                                      /*  temporary input               */
    00187   int32_t shift = (int32_t) S->postShift + 1;    /*  Shift to be applied to the output */
    00188   uint32_t sample, stage = S->numStages;         /*  loop counters                     */
    00189
    00190
    00191   do
    00192   {
    00193     /* Reading the coefficients */
    00194     b0 = *pCoeffs++;
    00195     b1 = *pCoeffs++;
    00196     b2 = *pCoeffs++;
    00197     a1 = *pCoeffs++;
    00198     a2 = *pCoeffs++;
    00199
    00200     /* Reading the state values */
    00201     Xn1 = pState[0];
    00202     Xn2 = pState[1];
    00203     Yn1 = pState[2];
    00204     Yn2 = pState[3];
    00205
    00206     /* Apply loop unrolling and compute 4 output values simultaneously. */
    00207     /* The variable acc hold output value that is being computed and
    00208      * stored in the destination buffer
    00209      * acc =  b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
    00210      */
    00211
    00212     sample = blockSize >> 2u;
    00213
    00214     /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
    00215      ** a second loop below computes the remaining 1 to 3 samples. */
    00216     while(sample > 0u)
    00217     {
    00218       /* Read the input */
    00219       Xn = *pIn++;
    00220
    00221       /* The value is shifted to the MSB to perform 32x64 multiplication */
    00222       Xn = Xn << 32;
    00223
    00224       /* acc =  b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
    00225
    00226       /* acc =  b0 * x[n] */
    00227       acc = mult32x64(Xn, b0);
    00228       /* acc +=  b1 * x[n-1] */
    00229       acc += mult32x64(Xn1, b1);
    00230       /* acc +=  b[2] * x[n-2] */
    00231       acc += mult32x64(Xn2, b2);
    00232       /* acc +=  a1 * y[n-1] */
    00233       acc += mult32x64(Yn1, a1);
    00234       /* acc +=  a2 * y[n-2] */
    00235       acc += mult32x64(Yn2, a2);
    00236
    00237       /* The result is converted to 1.63 , Yn2 variable is reused */
    00238       Yn2 = acc << shift;
    00239
    00240       /* Store the output in the destination buffer in 1.31 format. */
    00241       *pOut++ = (q31_t) (acc >> (32 - shift));
    00242
    00243       /* Read the second input into Xn2, to reuse the value */
    00244       Xn2 = *pIn++;
    00245
    00246       /* The value is shifted to the MSB to perform 32x64 multiplication */
    00247       Xn2 = Xn2 << 32;
    00248
    00249       /* acc =  b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
    00250
    00251       /* acc =  b0 * x[n] */
    00252       acc = mult32x64(Xn2, b0);
    00253       /* acc +=  b1 * x[n-1] */
    00254       acc += mult32x64(Xn, b1);
    00255       /* acc +=  b[2] * x[n-2] */
    00256       acc += mult32x64(Xn1, b2);
    00257       /* acc +=  a1 * y[n-1] */
    00258       acc += mult32x64(Yn2, a1);
    00259       /* acc +=  a2 * y[n-2] */
    00260       acc += mult32x64(Yn1, a2);
    00261
    00262       /* The result is converted to 1.63, Yn1 variable is reused */
    00263       Yn1 = acc << shift;
    00264
    00265       /* The result is converted to 1.31 */
    00266       /* Store the output in the destination buffer. */
    00267       *pOut++ = (q31_t) (acc >> (32 - shift));
    00268
    00269       /* Read the third input into Xn1, to reuse the value */
    00270       Xn1 = *pIn++;
    00271
    00272       /* The value is shifted to the MSB to perform 32x64 multiplication */
    00273       Xn1 = Xn1 << 32;
    00274
    00275       /* acc =  b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
    00276       /* acc =  b0 * x[n] */
    00277       acc = mult32x64(Xn1, b0);
    00278       /* acc +=  b1 * x[n-1] */
    00279       acc += mult32x64(Xn2, b1);
    00280       /* acc +=  b[2] * x[n-2] */
    00281       acc += mult32x64(Xn, b2);
    00282       /* acc +=  a1 * y[n-1] */
    00283       acc += mult32x64(Yn1, a1);
    00284       /* acc +=  a2 * y[n-2] */
    00285       acc += mult32x64(Yn2, a2);
    00286
    00287       /* The result is converted to 1.63, Yn2 variable is reused  */
    00288       Yn2 = acc << shift;
    00289
    00290       /* Store the output in the destination buffer in 1.31 format. */
    00291       *pOut++ = (q31_t) (acc >> (32 - shift));
    00292
    00293       /* Read the fourth input into Xn, to reuse the value */
    00294       Xn = *pIn++;
    00295
    00296       /* The value is shifted to the MSB to perform 32x64 multiplication */
    00297       Xn = Xn << 32;
    00298
    00299       /* acc =  b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
    00300       /* acc =  b0 * x[n] */
    00301       acc = mult32x64(Xn, b0);
    00302       /* acc +=  b1 * x[n-1] */
    00303       acc += mult32x64(Xn1, b1);
    00304       /* acc +=  b[2] * x[n-2] */
    00305       acc += mult32x64(Xn2, b2);
    00306       /* acc +=  a1 * y[n-1] */
    00307       acc += mult32x64(Yn2, a1);
    00308       /* acc +=  a2 * y[n-2] */
    00309       acc += mult32x64(Yn1, a2);
    00310
    00311       /* The result is converted to 1.63, Yn1 variable is reused  */
    00312       Yn1 = acc << shift;
    00313
    00314       /* Every time after the output is computed state should be updated. */
    00315       /* The states should be updated as:  */
    00316       /* Xn2 = Xn1    */
    00317       /* Xn1 = Xn     */
    00318       /* Yn2 = Yn1    */
    00319       /* Yn1 = acc    */
    00320       Xn2 = Xn1;
    00321       Xn1 = Xn;
    00322
    00323       /* Store the output in the destination buffer in 1.31 format. */
    00324       *pOut++ = (q31_t) (acc >> (32 - shift));
    00325
    00326       /* decrement the loop counter */
    00327       sample--;
    00328     }
    00329
    00330     /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
    00331      ** No loop unrolling is used. */
    00332     sample = (blockSize & 0x3u);
    00333
    00334     while(sample > 0u)
    00335     {
    00336       /* Read the input */
    00337       Xn = *pIn++;
    00338
    00339       /* The value is shifted to the MSB to perform 32x64 multiplication */
    00340       Xn = Xn << 32;
    00341
    00342       /* acc =  b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */
    00343       /* acc =  b0 * x[n] */
    00344       acc = mult32x64(Xn, b0);
    00345       /* acc +=  b1 * x[n-1] */
    00346       acc += mult32x64(Xn1, b1);
    00347       /* acc +=  b[2] * x[n-2] */
    00348       acc += mult32x64(Xn2, b2);
    00349       /* acc +=  a1 * y[n-1] */
    00350       acc += mult32x64(Yn1, a1);
    00351       /* acc +=  a2 * y[n-2] */
    00352       acc += mult32x64(Yn2, a2);
    00353
    00354       /* Every time after the output is computed state should be updated. */
    00355       /* The states should be updated as:  */
    00356       /* Xn2 = Xn1    */
    00357       /* Xn1 = Xn     */
    00358       /* Yn2 = Yn1    */
    00359       /* Yn1 = acc    */
    00360       Xn2 = Xn1;
    00361       Xn1 = Xn;
    00362       Yn2 = Yn1;
    00363       Yn1 = acc << shift;
    00364
    00365       /* Store the output in the destination buffer in 1.31 format. */
    00366       *pOut++ = (q31_t) (acc >> (32 - shift));
    00367
    00368       /* decrement the loop counter */
    00369       sample--;
    00370     }
    00371
    00372     /*  The first stage output is given as input to the second stage. */
    00373     pIn = pDst;
    00374
    00375     /* Reset to destination buffer working pointer */
    00376     pOut = pDst;
    00377
    00378     /*  Store the updated state variables back into the pState array */
    00379     *pState++ = Xn1;
    00380     *pState++ = Xn2;
    00381     *pState++ = Yn1;
    00382     *pState++ = Yn2;
    00383
    00384   } while(--stage);
    00385 }
    00386

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines