Home | History | Annotate | Download | only in ilbc
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /******************************************************************
     12 
     13  iLBC Speech Coder ANSI-C Source Code
     14 
     15  WebRtcIlbcfix_CbSearchCore.c
     16 
     17 ******************************************************************/
     18 
     19 #include "defines.h"
     20 #include "constants.h"
     21 
     22 void WebRtcIlbcfix_CbSearchCore(
     23     int32_t *cDot,    /* (i) Cross Correlation */
     24     int16_t range,    /* (i) Search range */
     25     int16_t stage,    /* (i) Stage of this search */
     26     int16_t *inverseEnergy,  /* (i) Inversed energy */
     27     int16_t *inverseEnergyShift, /* (i) Shifts of inversed energy
     28                                            with the offset 2*16-29 */
     29     int32_t *Crit,    /* (o) The criteria */
     30     int16_t *bestIndex,   /* (o) Index that corresponds to
     31                                                    maximum criteria (in this
     32                                                    vector) */
     33     int32_t *bestCrit,   /* (o) Value of critera for the
     34                                                    chosen index */
     35     int16_t *bestCritSh)   /* (o) The domain of the chosen
     36                                                    criteria */
     37 {
     38   int32_t maxW32, tmp32;
     39   int16_t max, sh, tmp16;
     40   int i;
     41   int32_t *cDotPtr;
     42   int16_t cDotSqW16;
     43   int16_t *inverseEnergyPtr;
     44   int32_t *critPtr;
     45   int16_t *inverseEnergyShiftPtr;
     46 
     47   /* Don't allow negative values for stage 0 */
     48   if (stage==0) {
     49     cDotPtr=cDot;
     50     for (i=0;i<range;i++) {
     51       *cDotPtr=WEBRTC_SPL_MAX(0, (*cDotPtr));
     52       cDotPtr++;
     53     }
     54   }
     55 
     56   /* Normalize cDot to int16_t, calculate the square of cDot and store the upper int16_t */
     57   maxW32 = WebRtcSpl_MaxAbsValueW32(cDot, range);
     58 
     59   sh = (int16_t)WebRtcSpl_NormW32(maxW32);
     60   cDotPtr = cDot;
     61   inverseEnergyPtr = inverseEnergy;
     62   critPtr = Crit;
     63   inverseEnergyShiftPtr=inverseEnergyShift;
     64   max=WEBRTC_SPL_WORD16_MIN;
     65 
     66   for (i=0;i<range;i++) {
     67     /* Calculate cDot*cDot and put the result in a int16_t */
     68     tmp32 = WEBRTC_SPL_LSHIFT_W32(*cDotPtr,sh);
     69     tmp16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32,16);
     70     cDotSqW16 = (int16_t)(((int32_t)(tmp16)*(tmp16))>>16);
     71 
     72     /* Calculate the criteria (cDot*cDot/energy) */
     73     *critPtr=WEBRTC_SPL_MUL_16_16(cDotSqW16, (*inverseEnergyPtr));
     74 
     75     /* Extract the maximum shift value under the constraint
     76        that the criteria is not zero */
     77     if ((*critPtr)!=0) {
     78       max = WEBRTC_SPL_MAX((*inverseEnergyShiftPtr), max);
     79     }
     80 
     81     inverseEnergyPtr++;
     82     inverseEnergyShiftPtr++;
     83     critPtr++;
     84     cDotPtr++;
     85   }
     86 
     87   /* If no max shifts still at initialization value, set shift to zero */
     88   if (max==WEBRTC_SPL_WORD16_MIN) {
     89     max = 0;
     90   }
     91 
     92   /* Modify the criterias, so that all of them use the same Q domain */
     93   critPtr=Crit;
     94   inverseEnergyShiftPtr=inverseEnergyShift;
     95   for (i=0;i<range;i++) {
     96     /* Guarantee that the shift value is less than 16
     97        in order to simplify for DSP's (and guard against >31) */
     98     tmp16 = WEBRTC_SPL_MIN(16, max-(*inverseEnergyShiftPtr));
     99 
    100     (*critPtr)=WEBRTC_SPL_SHIFT_W32((*critPtr),-tmp16);
    101     critPtr++;
    102     inverseEnergyShiftPtr++;
    103   }
    104 
    105   /* Find the index of the best value */
    106   *bestIndex = WebRtcSpl_MaxIndexW32(Crit, range);
    107   *bestCrit = Crit[*bestIndex];
    108 
    109   /* Calculate total shifts of this criteria */
    110   *bestCritSh = 32 - 2*sh + max;
    111 
    112   return;
    113 }
    114