2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
11 /******************************************************************
13 iLBC Speech Coder ANSI-C Source Code
15 WebRtcIlbcfix_CbSearchCore.c
17 ******************************************************************/
20 #include "constants.h"
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
33 int32_t *bestCrit, /* (o) Value of critera for the
35 int16_t *bestCritSh) /* (o) The domain of the chosen
38 int32_t maxW32, tmp32;
39 int16_t max, sh, tmp16;
43 int16_t *inverseEnergyPtr;
45 int16_t *inverseEnergyShiftPtr;
47 /* Don't allow negative values for stage 0 */
50 for (i=0;i<range;i++) {
51 *cDotPtr=WEBRTC_SPL_MAX(0, (*cDotPtr));
56 /* Normalize cDot to int16_t, calculate the square of cDot and store the upper int16_t */
57 maxW32 = WebRtcSpl_MaxAbsValueW32(cDot, range);
59 sh = (int16_t)WebRtcSpl_NormW32(maxW32);
61 inverseEnergyPtr = inverseEnergy;
63 inverseEnergyShiftPtr=inverseEnergyShift;
64 max=WEBRTC_SPL_WORD16_MIN;
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)(tmp32 >> 16);
70 cDotSqW16 = (int16_t)(((int32_t)(tmp16)*(tmp16))>>16);
72 /* Calculate the criteria (cDot*cDot/energy) */
73 *critPtr=WEBRTC_SPL_MUL_16_16(cDotSqW16, (*inverseEnergyPtr));
75 /* Extract the maximum shift value under the constraint
76 that the criteria is not zero */
78 max = WEBRTC_SPL_MAX((*inverseEnergyShiftPtr), max);
82 inverseEnergyShiftPtr++;
87 /* If no max shifts still at initialization value, set shift to zero */
88 if (max==WEBRTC_SPL_WORD16_MIN) {
92 /* Modify the criterias, so that all of them use the same Q domain */
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));
100 (*critPtr)=WEBRTC_SPL_SHIFT_W32((*critPtr),-tmp16);
102 inverseEnergyShiftPtr++;
105 /* Find the index of the best value */
106 *bestIndex = WebRtcSpl_MaxIndexW32(Crit, range);
107 *bestCrit = Crit[*bestIndex];
109 /* Calculate total shifts of this criteria */
110 *bestCritSh = 32 - 2*sh + max;