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_Smooth.c 16 17******************************************************************/ 18 19#include "defines.h" 20#include "constants.h" 21#include "smooth_out_data.h" 22 23/*----------------------------------------------------------------* 24 * find the smoothed output data 25 *---------------------------------------------------------------*/ 26 27void WebRtcIlbcfix_Smooth( 28 int16_t *odata, /* (o) smoothed output */ 29 int16_t *current, /* (i) the un enhanced residual for 30 this block */ 31 int16_t *surround /* (i) The approximation from the 32 surrounding sequences */ 33 ) { 34 int16_t maxtot, scale, scale1, scale2; 35 int16_t A, B, C, denomW16; 36 int32_t B_W32, denom, num; 37 int32_t errs; 38 int32_t w00,w10,w11, endiff, crit; 39 int32_t w00prim, w10prim, w11_div_w00; 40 int16_t w11prim; 41 int16_t bitsw00, bitsw10, bitsw11; 42 int32_t w11w00, w10w10, w00w00; 43 int16_t max1, max2; 44 45 /* compute some inner products (ensure no overflow by first calculating proper scale factor) */ 46 47 w00 = w10 = w11 = 0; 48 49 max1=WebRtcSpl_MaxAbsValueW16(current, ENH_BLOCKL); 50 max2=WebRtcSpl_MaxAbsValueW16(surround, ENH_BLOCKL); 51 maxtot=WEBRTC_SPL_MAX(max1, max2); 52 53 scale=WebRtcSpl_GetSizeInBits(maxtot); 54 scale = (int16_t)(2 * scale) - 26; 55 scale=WEBRTC_SPL_MAX(0, scale); 56 57 w00=WebRtcSpl_DotProductWithScale(current,current,ENH_BLOCKL,scale); 58 w11=WebRtcSpl_DotProductWithScale(surround,surround,ENH_BLOCKL,scale); 59 w10=WebRtcSpl_DotProductWithScale(surround,current,ENH_BLOCKL,scale); 60 61 if (w00<0) w00 = WEBRTC_SPL_WORD32_MAX; 62 if (w11<0) w11 = WEBRTC_SPL_WORD32_MAX; 63 64 /* Rescale w00 and w11 to w00prim and w11prim, so that w00prim/w11prim 65 is in Q16 */ 66 67 bitsw00 = WebRtcSpl_GetSizeInBits(w00); 68 bitsw11 = WebRtcSpl_GetSizeInBits(w11); 69 bitsw10 = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_ABS_W32(w10)); 70 scale1 = 31 - bitsw00; 71 scale2 = 15 - bitsw11; 72 73 if (scale2>(scale1-16)) { 74 scale2 = scale1 - 16; 75 } else { 76 scale1 = scale2 + 16; 77 } 78 79 w00prim = w00 << scale1; 80 w11prim = (int16_t) WEBRTC_SPL_SHIFT_W32(w11, scale2); 81 82 /* Perform C = sqrt(w11/w00) (C is in Q11 since (16+6)/2=11) */ 83 if (w11prim>64) { 84 endiff = WebRtcSpl_DivW32W16(w00prim, w11prim) << 6; 85 C = (int16_t)WebRtcSpl_SqrtFloor(endiff); /* C is in Q11 */ 86 } else { 87 C = 1; 88 } 89 90 /* first try enhancement without power-constraint */ 91 92 errs = WebRtcIlbcfix_Smooth_odata(odata, current, surround, C); 93 94 95 96 /* if constraint violated by first try, add constraint */ 97 98 if ( (6-scale+scale1) > 31) { 99 crit=0; 100 } else { 101 /* crit = 0.05 * w00 (Result in Q-6) */ 102 crit = WEBRTC_SPL_SHIFT_W32( 103 WEBRTC_SPL_MUL(ENH_A0, w00prim >> 14), 104 -(6-scale+scale1)); 105 } 106 107 if (errs > crit) { 108 109 if( w00 < 1) { 110 w00=1; 111 } 112 113 /* Calculate w11*w00, w10*w10 and w00*w00 in the same Q domain */ 114 115 scale1 = bitsw00-15; 116 scale2 = bitsw11-15; 117 118 if (scale2>scale1) { 119 scale = scale2; 120 } else { 121 scale = scale1; 122 } 123 124 w11w00 = (int16_t)WEBRTC_SPL_SHIFT_W32(w11, -scale) * 125 (int16_t)WEBRTC_SPL_SHIFT_W32(w00, -scale); 126 127 w10w10 = (int16_t)WEBRTC_SPL_SHIFT_W32(w10, -scale) * 128 (int16_t)WEBRTC_SPL_SHIFT_W32(w10, -scale); 129 130 w00w00 = (int16_t)WEBRTC_SPL_SHIFT_W32(w00, -scale) * 131 (int16_t)WEBRTC_SPL_SHIFT_W32(w00, -scale); 132 133 /* Calculate (w11*w00-w10*w10)/(w00*w00) in Q16 */ 134 if (w00w00>65536) { 135 endiff = (w11w00-w10w10); 136 endiff = WEBRTC_SPL_MAX(0, endiff); 137 /* denom is in Q16 */ 138 denom = WebRtcSpl_DivW32W16(endiff, (int16_t)(w00w00 >> 16)); 139 } else { 140 denom = 65536; 141 } 142 143 if( denom > 7){ /* eliminates numerical problems 144 for if smooth */ 145 146 scale=WebRtcSpl_GetSizeInBits(denom)-15; 147 148 if (scale>0) { 149 /* denomW16 is in Q(16+scale) */ 150 denomW16 = (int16_t)(denom >> scale); 151 152 /* num in Q(34-scale) */ 153 num = ENH_A0_MINUS_A0A0DIV4 >> scale; 154 } else { 155 /* denomW16 is in Q16 */ 156 denomW16=(int16_t)denom; 157 158 /* num in Q34 */ 159 num=ENH_A0_MINUS_A0A0DIV4; 160 } 161 162 /* A sqrt( (ENH_A0-(ENH_A0^2)/4)*(w00*w00)/(w11*w00 + w10*w10) ) in Q9 */ 163 A = (int16_t)WebRtcSpl_SqrtFloor(WebRtcSpl_DivW32W16(num, denomW16)); 164 165 /* B_W32 is in Q30 ( B = 1 - ENH_A0/2 - A * w10/w00 ) */ 166 scale1 = 31-bitsw10; 167 scale2 = 21-scale1; 168 w10prim = w10 << scale1; 169 w00prim = WEBRTC_SPL_SHIFT_W32(w00, -scale2); 170 scale = bitsw00-scale2-15; 171 172 if (scale>0) { 173 w10prim >>= scale; 174 w00prim >>= scale; 175 } 176 177 if ((w00prim>0)&&(w10prim>0)) { 178 w11_div_w00=WebRtcSpl_DivW32W16(w10prim, (int16_t)w00prim); 179 180 if (WebRtcSpl_GetSizeInBits(w11_div_w00)+WebRtcSpl_GetSizeInBits(A)>31) { 181 B_W32 = 0; 182 } else { 183 B_W32 = (int32_t)1073741824 - (int32_t)ENH_A0DIV2 - 184 WEBRTC_SPL_MUL(A, w11_div_w00); 185 } 186 B = (int16_t)(B_W32 >> 16); /* B in Q14. */ 187 } else { 188 /* No smoothing */ 189 A = 0; 190 B = 16384; /* 1 in Q14 */ 191 } 192 } 193 else{ /* essentially no difference between cycles; 194 smoothing not needed */ 195 196 A = 0; 197 B = 16384; /* 1 in Q14 */ 198 } 199 200 /* create smoothed sequence */ 201 202 WebRtcSpl_ScaleAndAddVectors(surround, A, 9, 203 current, B, 14, 204 odata, ENH_BLOCKL); 205 } 206 return; 207} 208