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