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 "modules/audio_coding/codecs/ilbc/cb_search_core.h"
20 
21 #include "modules/audio_coding/codecs/ilbc/constants.h"
22 #include "modules/audio_coding/codecs/ilbc/defines.h"
23 
WebRtcIlbcfix_CbSearchCore(int32_t * cDot,size_t range,int16_t stage,int16_t * inverseEnergy,int16_t * inverseEnergyShift,int32_t * Crit,size_t * bestIndex,int32_t * bestCrit,int16_t * bestCritSh)24 void WebRtcIlbcfix_CbSearchCore(
25     int32_t *cDot,    /* (i) Cross Correlation */
26     size_t range,    /* (i) Search range */
27     int16_t stage,    /* (i) Stage of this search */
28     int16_t *inverseEnergy,  /* (i) Inversed energy */
29     int16_t *inverseEnergyShift, /* (i) Shifts of inversed energy
30                                            with the offset 2*16-29 */
31     int32_t *Crit,    /* (o) The criteria */
32     size_t *bestIndex,   /* (o) Index that corresponds to
33                                                    maximum criteria (in this
34                                                    vector) */
35     int32_t *bestCrit,   /* (o) Value of critera for the
36                                                    chosen index */
37     int16_t *bestCritSh)   /* (o) The domain of the chosen
38                                                    criteria */
39 {
40   int32_t maxW32, tmp32;
41   int16_t max, sh, tmp16;
42   size_t i;
43   int32_t *cDotPtr;
44   int16_t cDotSqW16;
45   int16_t *inverseEnergyPtr;
46   int32_t *critPtr;
47   int16_t *inverseEnergyShiftPtr;
48 
49   /* Don't allow negative values for stage 0 */
50   if (stage==0) {
51     cDotPtr=cDot;
52     for (i=0;i<range;i++) {
53       *cDotPtr=WEBRTC_SPL_MAX(0, (*cDotPtr));
54       cDotPtr++;
55     }
56   }
57 
58   /* Normalize cDot to int16_t, calculate the square of cDot and store the upper int16_t */
59   maxW32 = WebRtcSpl_MaxAbsValueW32(cDot, range);
60 
61   sh = (int16_t)WebRtcSpl_NormW32(maxW32);
62   cDotPtr = cDot;
63   inverseEnergyPtr = inverseEnergy;
64   critPtr = Crit;
65   inverseEnergyShiftPtr=inverseEnergyShift;
66   max=WEBRTC_SPL_WORD16_MIN;
67 
68   for (i=0;i<range;i++) {
69     /* Calculate cDot*cDot and put the result in a int16_t */
70     tmp32 = *cDotPtr << sh;
71     tmp16 = (int16_t)(tmp32 >> 16);
72     cDotSqW16 = (int16_t)(((int32_t)(tmp16)*(tmp16))>>16);
73 
74     /* Calculate the criteria (cDot*cDot/energy) */
75     *critPtr = cDotSqW16 * *inverseEnergyPtr;
76 
77     /* Extract the maximum shift value under the constraint
78        that the criteria is not zero */
79     if ((*critPtr)!=0) {
80       max = WEBRTC_SPL_MAX((*inverseEnergyShiftPtr), max);
81     }
82 
83     inverseEnergyPtr++;
84     inverseEnergyShiftPtr++;
85     critPtr++;
86     cDotPtr++;
87   }
88 
89   /* If no max shifts still at initialization value, set shift to zero */
90   if (max==WEBRTC_SPL_WORD16_MIN) {
91     max = 0;
92   }
93 
94   /* Modify the criterias, so that all of them use the same Q domain */
95   critPtr=Crit;
96   inverseEnergyShiftPtr=inverseEnergyShift;
97   for (i=0;i<range;i++) {
98     /* Guarantee that the shift value is less than 16
99        in order to simplify for DSP's (and guard against >31) */
100     tmp16 = WEBRTC_SPL_MIN(16, max-(*inverseEnergyShiftPtr));
101 
102     (*critPtr)=WEBRTC_SPL_SHIFT_W32((*critPtr),-tmp16);
103     critPtr++;
104     inverseEnergyShiftPtr++;
105   }
106 
107   /* Find the index of the best value */
108   *bestIndex = WebRtcSpl_MaxIndexW32(Crit, range);
109   *bestCrit = Crit[*bestIndex];
110 
111   /* Calculate total shifts of this criteria */
112   *bestCritSh = 32 - 2*sh + max;
113 
114   return;
115 }
116