CMSIS DSP Software Library: arm_correlate_q15.c Source File

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

- File List
- Globals

# arm_correlate_q15.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_correlate_q15.c
    00009 *
    00010 * Description:  Correlation of Q15 sequences.
    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 * Version 0.0.7  2010/06/10
    00030 *    Misra-C changes done
    00031 *
    00032 * -------------------------------------------------------------------- */
    00033
    00034 #include "arm_math.h"
    00035
    00068 void arm_correlate_q15(
    00069   q15_t * pSrcA,
    00070   uint32_t srcALen,
    00071   q15_t * pSrcB,
    00072   uint32_t srcBLen,
    00073   q15_t * pDst)
    00074 {
    00075
    00076 #ifndef ARM_MATH_CM0
    00077
    00078   /* Run the below code for Cortex-M4 and Cortex-M3 */
    00079
    00080   q15_t *pIn1;                                   /* inputA pointer               */
    00081   q15_t *pIn2;                                   /* inputB pointer               */
    00082   q15_t *pOut = pDst;                            /* output pointer               */
    00083   q63_t sum, acc0, acc1, acc2, acc3;             /* Accumulators                  */
    00084   q15_t *px;                                     /* Intermediate inputA pointer  */
    00085   q15_t *py;                                     /* Intermediate inputB pointer  */
    00086   q15_t *pSrc1;                                  /* Intermediate pointers        */
    00087   q31_t x0, x1, x2, x3, c0;                      /* temporary variables for holding input and coefficient values */
    00088   uint32_t j, k = 0u, count, blkCnt, outBlockSize, blockSize1, blockSize2, blockSize3;  /* loop counter                 */
    00089   int32_t inc = 1;                               /* Destination address modifier */
    00090   q31_t *pb;                                     /* 32 bit pointer for inputB buffer */
    00091
    00092
    00093   /* The algorithm implementation is based on the lengths of the inputs. */
    00094   /* srcB is always made to slide across srcA. */
    00095   /* So srcBLen is always considered as shorter or equal to srcALen */
    00096   /* But CORR(x, y) is reverse of CORR(y, x) */
    00097   /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */
    00098   /* and the destination pointer modifier, inc is set to -1 */
    00099   /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */
    00100   /* But to improve the performance,
    00101    * we include zeroes in the output instead of zero padding either of the the inputs*/
    00102   /* If srcALen > srcBLen,
    00103    * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */
    00104   /* If srcALen < srcBLen,
    00105    * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */
    00106   if(srcALen >= srcBLen)
    00107   {
    00108     /* Initialization of inputA pointer */
    00109     pIn1 = (pSrcA);
    00110
    00111     /* Initialization of inputB pointer */
    00112     pIn2 = (pSrcB);
    00113
    00114     /* Number of output samples is calculated */
    00115     outBlockSize = (2u * srcALen) - 1u;
    00116
    00117     /* When srcALen > srcBLen, zero padding is done to srcB
    00118      * to make their lengths equal.
    00119      * Instead, (outBlockSize - (srcALen + srcBLen - 1))
    00120      * number of output samples are made zero */
    00121     j = outBlockSize - (srcALen + (srcBLen - 1u));
    00122
    00123     /* Updating the pointer position to non zero value */
    00124     pOut += j;
    00125
    00126   }
    00127   else
    00128   {
    00129     /* Initialization of inputA pointer */
    00130     pIn1 = (pSrcB);
    00131
    00132     /* Initialization of inputB pointer */
    00133     pIn2 = (pSrcA);
    00134
    00135     /* srcBLen is always considered as shorter or equal to srcALen */
    00136     j = srcBLen;
    00137     srcBLen = srcALen;
    00138     srcALen = j;
    00139
    00140     /* CORR(x, y) = Reverse order(CORR(y, x)) */
    00141     /* Hence set the destination pointer to point to the last output sample */
    00142     pOut = pDst + ((srcALen + srcBLen) - 2u);
    00143
    00144     /* Destination address modifier is set to -1 */
    00145     inc = -1;
    00146
    00147   }
    00148
    00149   /* The function is internally
    00150    * divided into three parts according to the number of multiplications that has to be
    00151    * taken place between inputA samples and inputB samples. In the first part of the
    00152    * algorithm, the multiplications increase by one for every iteration.
    00153    * In the second part of the algorithm, srcBLen number of multiplications are done.
    00154    * In the third part of the algorithm, the multiplications decrease by one
    00155    * for every iteration.*/
    00156   /* The algorithm is implemented in three stages.
    00157    * The loop counters of each stage is initiated here. */
    00158   blockSize1 = srcBLen - 1u;
    00159   blockSize2 = srcALen - (srcBLen - 1u);
    00160   blockSize3 = blockSize1;
    00161
    00162   /* --------------------------
    00163    * Initializations of stage1
    00164    * -------------------------*/
    00165
    00166   /* sum = x[0] * y[srcBlen - 1]
    00167    * sum = x[0] * y[srcBlen - 2] + x[1] * y[srcBlen - 1]
    00168    * ....
    00169    * sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen - 1] * y[srcBLen - 1]
    00170    */
    00171
    00172   /* In this stage the MAC operations are increased by 1 for every iteration.
    00173      The count variable holds the number of MAC operations performed */
    00174   count = 1u;
    00175
    00176   /* Working pointer of inputA */
    00177   px = pIn1;
    00178
    00179   /* Working pointer of inputB */
    00180   pSrc1 = pIn2 + (srcBLen - 1u);
    00181   py = pSrc1;
    00182
    00183   /* ------------------------
    00184    * Stage1 process
    00185    * ----------------------*/
    00186
    00187   /* The first loop starts here */
    00188   while(blockSize1 > 0u)
    00189   {
    00190     /* Accumulator is made zero for every iteration */
    00191     sum = 0;
    00192
    00193     /* Apply loop unrolling and compute 4 MACs simultaneously. */
    00194     k = count >> 2;
    00195
    00196     /* First part of the processing with loop unrolling.  Compute 4 MACs at a time.
    00197      ** a second loop below computes MACs for the remaining 1 to 3 samples. */
    00198     while(k > 0u)
    00199     {
    00200       /* x[0] * y[srcBLen - 4] , x[1] * y[srcBLen - 3] */
    00201       sum = __SMLALD(*__SIMD32(px)++, *__SIMD32(py)++, sum);
    00202       /* x[3] * y[srcBLen - 1] , x[2] * y[srcBLen - 2] */
    00203       sum = __SMLALD(*__SIMD32(px)++, *__SIMD32(py)++, sum);
    00204
    00205       /* Decrement the loop counter */
    00206       k--;
    00207     }
    00208
    00209     /* If the count is not a multiple of 4, compute any remaining MACs here.
    00210      ** No loop unrolling is used. */
    00211     k = count % 0x4u;
    00212
    00213     while(k > 0u)
    00214     {
    00215       /* Perform the multiply-accumulates */
    00216       /* x[0] * y[srcBLen - 1] */
    00217       sum = __SMLALD(*px++, *py++, sum);
    00218
    00219       /* Decrement the loop counter */
    00220       k--;
    00221     }
    00222
    00223     /* Store the result in the accumulator in the destination buffer. */
    00224     *pOut = (q15_t) (__SSAT((sum >> 15), 16));
    00225     /* Destination pointer is updated according to the address modifier, inc */
    00226     pOut += inc;
    00227
    00228     /* Update the inputA and inputB pointers for next MAC calculation */
    00229     py = pSrc1 - count;
    00230     px = pIn1;
    00231
    00232     /* Increment the MAC count */
    00233     count++;
    00234
    00235     /* Decrement the loop counter */
    00236     blockSize1--;
    00237   }
    00238
    00239   /* --------------------------
    00240    * Initializations of stage2
    00241    * ------------------------*/
    00242
    00243   /* sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen-1] * y[srcBLen-1]
    00244    * sum = x[1] * y[0] + x[2] * y[1] +...+ x[srcBLen] * y[srcBLen-1]
    00245    * ....
    00246    * sum = x[srcALen-srcBLen-2] * y[0] + x[srcALen-srcBLen-1] * y[1] +...+ x[srcALen-1] * y[srcBLen-1]
    00247    */
    00248
    00249   /* Working pointer of inputA */
    00250   px = pIn1;
    00251
    00252   /* Working pointer of inputB */
    00253   py = pIn2;
    00254
    00255   /* Initialize inputB pointer of type q31 */
    00256   pb = (q31_t *) (py);
    00257
    00258   /* count is index by which the pointer pIn1 to be incremented */
    00259   count = 0u;
    00260
    00261   /* -------------------
    00262    * Stage2 process
    00263    * ------------------*/
    00264
    00265   /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed.
    00266    * So, to loop unroll over blockSize2,
    00267    * srcBLen should be greater than or equal to 4, to loop unroll the srcBLen loop */
    00268   if(srcBLen >= 4u)
    00269   {
    00270     /* Loop unroll over blockSize2, by 4 */
    00271     blkCnt = blockSize2 >> 2u;
    00272
    00273     while(blkCnt > 0u)
    00274     {
    00275       /* Set all accumulators to zero */
    00276       acc0 = 0;
    00277       acc1 = 0;
    00278       acc2 = 0;
    00279       acc3 = 0;
    00280
    00281       /* read x[0], x[1] samples */
    00282       x0 = *(q31_t *) (px++);
    00283       /* read x[1], x[2] samples */
    00284       x1 = *(q31_t *) (px++);
    00285
    00286       /* Apply loop unrolling and compute 4 MACs simultaneously. */
    00287       k = srcBLen >> 2u;
    00288
    00289       /* First part of the processing with loop unrolling.  Compute 4 MACs at a time.
    00290        ** a second loop below computes MACs for the remaining 1 to 3 samples. */
    00291       do
    00292       {
    00293         /* Read the first two inputB samples using SIMD:
    00294          * y[0] and y[1] */
    00295         c0 = *(pb++);
    00296
    00297         /* acc0 +=  x[0] * y[0] + x[1] * y[1] */
    00298         acc0 = __SMLALD(x0, c0, acc0);
    00299
    00300         /* acc1 +=  x[1] * y[0] + x[2] * y[1] */
    00301         acc1 = __SMLALD(x1, c0, acc1);
    00302
    00303         /* Read x[2], x[3] */
    00304         x2 = *(q31_t *) (px++);
    00305
    00306         /* Read x[3], x[4] */
    00307         x3 = *(q31_t *) (px++);
    00308
    00309         /* acc2 +=  x[2] * y[0] + x[3] * y[1] */
    00310         acc2 = __SMLALD(x2, c0, acc2);
    00311
    00312         /* acc3 +=  x[3] * y[0] + x[4] * y[1] */
    00313         acc3 = __SMLALD(x3, c0, acc3);
    00314
    00315         /* Read y[2] and y[3] */
    00316         c0 = *(pb++);
    00317
    00318         /* acc0 +=  x[2] * y[2] + x[3] * y[3] */
    00319         acc0 = __SMLALD(x2, c0, acc0);
    00320
    00321         /* acc1 +=  x[3] * y[2] + x[4] * y[3] */
    00322         acc1 = __SMLALD(x3, c0, acc1);
    00323
    00324         /* Read x[4], x[5] */
    00325         x0 = *(q31_t *) (px++);
    00326
    00327         /* Read x[5], x[6] */
    00328         x1 = *(q31_t *) (px++);
    00329
    00330         /* acc2 +=  x[4] * y[2] + x[5] * y[3] */
    00331         acc2 = __SMLALD(x0, c0, acc2);
    00332
    00333         /* acc3 +=  x[5] * y[2] + x[6] * y[3] */
    00334         acc3 = __SMLALD(x1, c0, acc3);
    00335
    00336       } while(--k);
    00337
    00338       /* For the next MAC operations, SIMD is not used
    00339        * So, the 16 bit pointer if inputB, py is updated */
    00340       py = (q15_t *) (pb);
    00341
    00342       /* If the srcBLen is not a multiple of 4, compute any remaining MACs here.
    00343        ** No loop unrolling is used. */
    00344       k = srcBLen % 0x4u;
    00345
    00346       if(k == 1u)
    00347       {
    00348         /* Read y[4] */
    00349         c0 = *py;
    00350 #ifdef  ARM_MATH_BIG_ENDIAN
    00351
    00352         c0 = c0 << 16u;
    00353
    00354 #else
    00355
    00356         c0 = c0 & 0x0000FFFF;
    00357
    00358 #endif /*      #ifdef  ARM_MATH_BIG_ENDIAN     */
    00359         /* Read x[7] */
    00360         x3 = *(q31_t *) px++;
    00361
    00362         /* Perform the multiply-accumulates */
    00363         acc0 = __SMLALD(x0, c0, acc0);
    00364         acc1 = __SMLALD(x1, c0, acc1);
    00365         acc2 = __SMLALDX(x1, c0, acc2);
    00366         acc3 = __SMLALDX(x3, c0, acc3);
    00367       }
    00368
    00369       if(k == 2u)
    00370       {
    00371         /* Read y[4], y[5] */
    00372         c0 = *(pb);
    00373
    00374         /* Read x[7], x[8] */
    00375         x3 = *(q31_t *) px++;
    00376
    00377         /* Read x[9] */
    00378         x2 = *(q31_t *) px++;
    00379
    00380         /* Perform the multiply-accumulates */
    00381         acc0 = __SMLALD(x0, c0, acc0);
    00382         acc1 = __SMLALD(x1, c0, acc1);
    00383         acc2 = __SMLALD(x3, c0, acc2);
    00384         acc3 = __SMLALD(x2, c0, acc3);
    00385       }
    00386
    00387       if(k == 3u)
    00388       {
    00389         /* Read y[4], y[5] */
    00390         c0 = *pb++;
    00391
    00392         /* Read x[7], x[8] */
    00393         x3 = *(q31_t *) px++;
    00394
    00395         /* Read x[9] */
    00396         x2 = *(q31_t *) px++;
    00397
    00398         /* Perform the multiply-accumulates */
    00399         acc0 = __SMLALD(x0, c0, acc0);
    00400         acc1 = __SMLALD(x1, c0, acc1);
    00401         acc2 = __SMLALD(x3, c0, acc2);
    00402         acc3 = __SMLALD(x2, c0, acc3);
    00403
    00404         /* Read y[6] */
    00405 #ifdef  ARM_MATH_BIG_ENDIAN
    00406
    00407         c0 = (*pb);
    00408         c0 = c0 & 0xFFFF0000;
    00409
    00410 #else
    00411
    00412         c0 = (q15_t) (*pb);
    00413         c0 = c0 & 0x0000FFFF;
    00414
    00415 #endif /*      #ifdef  ARM_MATH_BIG_ENDIAN     */
    00416         /* Read x[10] */
    00417         x3 = *(q31_t *) px++;
    00418
    00419         /* Perform the multiply-accumulates */
    00420         acc0 = __SMLALDX(x1, c0, acc0);
    00421         acc1 = __SMLALD(x2, c0, acc1);
    00422         acc2 = __SMLALDX(x2, c0, acc2);
    00423         acc3 = __SMLALDX(x3, c0, acc3);
    00424       }
    00425
    00426       /* Store the result in the accumulator in the destination buffer. */
    00427       *pOut = (q15_t) (__SSAT(acc0 >> 15, 16));
    00428       /* Destination pointer is updated according to the address modifier, inc */
    00429       pOut += inc;
    00430
    00431       *pOut = (q15_t) (__SSAT(acc1 >> 15, 16));
    00432       pOut += inc;
    00433
    00434       *pOut = (q15_t) (__SSAT(acc2 >> 15, 16));
    00435       pOut += inc;
    00436
    00437       *pOut = (q15_t) (__SSAT(acc3 >> 15, 16));
    00438       pOut += inc;
    00439
    00440       /* Increment the count by 4 as 4 output values are computed */
    00441       count += 4u;
    00442
    00443       /* Update the inputA and inputB pointers for next MAC calculation */
    00444       px = pIn1 + count;
    00445       py = pIn2;
    00446       pb = (q31_t *) (py);
    00447
    00448
    00449       /* Decrement the loop counter */
    00450       blkCnt--;
    00451     }
    00452
    00453     /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here.
    00454      ** No loop unrolling is used. */
    00455     blkCnt = blockSize2 % 0x4u;
    00456
    00457     while(blkCnt > 0u)
    00458     {
    00459       /* Accumulator is made zero for every iteration */
    00460       sum = 0;
    00461
    00462       /* Apply loop unrolling and compute 4 MACs simultaneously. */
    00463       k = srcBLen >> 2u;
    00464
    00465       /* First part of the processing with loop unrolling.  Compute 4 MACs at a time.
    00466        ** a second loop below computes MACs for the remaining 1 to 3 samples. */
    00467       while(k > 0u)
    00468       {
    00469         /* Perform the multiply-accumulates */
    00470         sum += ((q63_t) * px++ * *py++);
    00471         sum += ((q63_t) * px++ * *py++);
    00472         sum += ((q63_t) * px++ * *py++);
    00473         sum += ((q63_t) * px++ * *py++);
    00474
    00475         /* Decrement the loop counter */
    00476         k--;
    00477       }
    00478
    00479       /* If the srcBLen is not a multiple of 4, compute any remaining MACs here.
    00480        ** No loop unrolling is used. */
    00481       k = srcBLen % 0x4u;
    00482
    00483       while(k > 0u)
    00484       {
    00485         /* Perform the multiply-accumulates */
    00486         sum += ((q63_t) * px++ * *py++);
    00487
    00488         /* Decrement the loop counter */
    00489         k--;
    00490       }
    00491
    00492       /* Store the result in the accumulator in the destination buffer. */
    00493       *pOut = (q15_t) (__SSAT(sum >> 15, 16));
    00494       /* Destination pointer is updated according to the address modifier, inc */
    00495       pOut += inc;
    00496
    00497       /* Increment count by 1, as one output value is computed */
    00498       count++;
    00499
    00500       /* Update the inputA and inputB pointers for next MAC calculation */
    00501       px = pIn1 + count;
    00502       py = pIn2;
    00503
    00504       /* Decrement the loop counter */
    00505       blkCnt--;
    00506     }
    00507   }
    00508   else
    00509   {
    00510     /* If the srcBLen is not a multiple of 4,
    00511      * the blockSize2 loop cannot be unrolled by 4 */
    00512     blkCnt = blockSize2;
    00513
    00514     while(blkCnt > 0u)
    00515     {
    00516       /* Accumulator is made zero for every iteration */
    00517       sum = 0;
    00518
    00519       /* Loop over srcBLen */
    00520       k = srcBLen;
    00521
    00522       while(k > 0u)
    00523       {
    00524         /* Perform the multiply-accumulate */
    00525         sum += ((q63_t) * px++ * *py++);
    00526
    00527         /* Decrement the loop counter */
    00528         k--;
    00529       }
    00530
    00531       /* Store the result in the accumulator in the destination buffer. */
    00532       *pOut = (q15_t) (__SSAT(sum >> 15, 16));
    00533       /* Destination pointer is updated according to the address modifier, inc */
    00534       pOut += inc;
    00535
    00536       /* Increment the MAC count */
    00537       count++;
    00538
    00539       /* Update the inputA and inputB pointers for next MAC calculation */
    00540       px = pIn1 + count;
    00541       py = pIn2;
    00542
    00543       /* Decrement the loop counter */
    00544       blkCnt--;
    00545     }
    00546   }
    00547
    00548   /* --------------------------
    00549    * Initializations of stage3
    00550    * -------------------------*/
    00551
    00552   /* sum += x[srcALen-srcBLen+1] * y[0] + x[srcALen-srcBLen+2] * y[1] +...+ x[srcALen-1] * y[srcBLen-1]
    00553    * sum += x[srcALen-srcBLen+2] * y[0] + x[srcALen-srcBLen+3] * y[1] +...+ x[srcALen-1] * y[srcBLen-1]
    00554    * ....
    00555    * sum +=  x[srcALen-2] * y[0] + x[srcALen-1] * y[1]
    00556    * sum +=  x[srcALen-1] * y[0]
    00557    */
    00558
    00559   /* In this stage the MAC operations are decreased by 1 for every iteration.
    00560      The count variable holds the number of MAC operations performed */
    00561   count = srcBLen - 1u;
    00562
    00563   /* Working pointer of inputA */
    00564   pSrc1 = (pIn1 + srcALen) - (srcBLen - 1u);
    00565   px = pSrc1;
    00566
    00567   /* Working pointer of inputB */
    00568   py = pIn2;
    00569
    00570   /* -------------------
    00571    * Stage3 process
    00572    * ------------------*/
    00573
    00574   while(blockSize3 > 0u)
    00575   {
    00576     /* Accumulator is made zero for every iteration */
    00577     sum = 0;
    00578
    00579     /* Apply loop unrolling and compute 4 MACs simultaneously. */
    00580     k = count >> 2u;
    00581
    00582     /* First part of the processing with loop unrolling.  Compute 4 MACs at a time.
    00583      ** a second loop below computes MACs for the remaining 1 to 3 samples. */
    00584     while(k > 0u)
    00585     {
    00586       /* Perform the multiply-accumulates */
    00587       /* sum += x[srcALen - srcBLen + 4] * y[3] , sum += x[srcALen - srcBLen + 3] * y[2] */
    00588       sum = __SMLALD(*__SIMD32(px)++, *__SIMD32(py)++, sum);
    00589       /* sum += x[srcALen - srcBLen + 2] * y[1] , sum += x[srcALen - srcBLen + 1] * y[0] */
    00590       sum = __SMLALD(*__SIMD32(px)++, *__SIMD32(py)++, sum);
    00591
    00592       /* Decrement the loop counter */
    00593       k--;
    00594     }
    00595
    00596     /* If the count is not a multiple of 4, compute any remaining MACs here.
    00597      ** No loop unrolling is used. */
    00598     k = count % 0x4u;
    00599
    00600     while(k > 0u)
    00601     {
    00602       /* Perform the multiply-accumulates */
    00603       sum = __SMLALD(*px++, *py++, sum);
    00604
    00605       /* Decrement the loop counter */
    00606       k--;
    00607     }
    00608
    00609     /* Store the result in the accumulator in the destination buffer. */
    00610     *pOut = (q15_t) (__SSAT((sum >> 15), 16));
    00611     /* Destination pointer is updated according to the address modifier, inc */
    00612     pOut += inc;
    00613
    00614     /* Update the inputA and inputB pointers for next MAC calculation */
    00615     px = ++pSrc1;
    00616     py = pIn2;
    00617
    00618     /* Decrement the MAC count */
    00619     count--;
    00620
    00621     /* Decrement the loop counter */
    00622     blockSize3--;
    00623   }
    00624
    00625 #else
    00626
    00627 /* Run the below code for Cortex-M0 */
    00628
    00629   q15_t *pIn1 = pSrcA;                           /* inputA pointer               */
    00630   q15_t *pIn2 = pSrcB + (srcBLen - 1u);          /* inputB pointer               */
    00631   q63_t sum;                                     /* Accumulators                  */
    00632   uint32_t i = 0u, j;                            /* loop counters */
    00633   uint32_t inv = 0u;                             /* Reverse order flag */
    00634   uint32_t tot = 0u;                             /* Length */
    00635
    00636   /* The algorithm implementation is based on the lengths of the inputs. */
    00637   /* srcB is always made to slide across srcA. */
    00638   /* So srcBLen is always considered as shorter or equal to srcALen */
    00639   /* But CORR(x, y) is reverse of CORR(y, x) */
    00640   /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */
    00641   /* and a varaible, inv is set to 1 */
    00642   /* If lengths are not equal then zero pad has to be done to  make the two
    00643    * inputs of same length. But to improve the performance, we include zeroes
    00644    * in the output instead of zero padding either of the the inputs*/
    00645   /* If srcALen > srcBLen, (srcALen - srcBLen) zeroes has to included in the
    00646    * starting of the output buffer */
    00647   /* If srcALen < srcBLen, (srcALen - srcBLen) zeroes has to included in the
    00648    * ending of the output buffer */
    00649   /* Once the zero padding is done the remaining of the output is calcualted
    00650    * using convolution but with the shorter signal time shifted. */
    00651
    00652   /* Calculate the length of the remaining sequence */
    00653   tot = ((srcALen + srcBLen) - 2u);
    00654
    00655   if(srcALen > srcBLen)
    00656   {
    00657     /* Calculating the number of zeros to be padded to the output */
    00658     j = srcALen - srcBLen;
    00659
    00660     /* Initialise the pointer after zero padding */
    00661     pDst += j;
    00662   }
    00663
    00664   else if(srcALen < srcBLen)
    00665   {
    00666     /* Initialization to inputB pointer */
    00667     pIn1 = pSrcB;
    00668
    00669     /* Initialization to the end of inputA pointer */
    00670     pIn2 = pSrcA + (srcALen - 1u);
    00671
    00672     /* Initialisation of the pointer after zero padding */
    00673     pDst = pDst + tot;
    00674
    00675     /* Swapping the lengths */
    00676     j = srcALen;
    00677     srcALen = srcBLen;
    00678     srcBLen = j;
    00679
    00680     /* Setting the reverse flag */
    00681     inv = 1;
    00682
    00683   }
    00684
    00685   /* Loop to calculate convolution for output length number of times */
    00686   for (i = 0u; i <= tot; i++)
    00687   {
    00688     /* Initialize sum with zero to carry on MAC operations */
    00689     sum = 0;
    00690
    00691     /* Loop to perform MAC operations according to convolution equation */
    00692     for (j = 0u; j <= i; j++)
    00693     {
    00694       /* Check the array limitations */
    00695       if((((i - j) < srcBLen) && (j < srcALen)))
    00696       {
    00697         /* z[i] += x[i-j] * y[j] */
    00698         sum += ((q31_t) pIn1[j] * pIn2[-((int32_t) i - j)]);
    00699       }
    00700     }
    00701     /* Store the output in the destination buffer */
    00702     if(inv == 1)
    00703       *pDst-- = (q15_t) __SSAT((sum >> 15u), 16u);
    00704     else
    00705       *pDst++ = (q15_t) __SSAT((sum >> 15u), 16u);
    00706   }
    00707
    00708 #endif /*   #ifndef ARM_MATH_CM0 */
    00709
    00710 }
    00711

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines