Have a guard on computing nrg to avoid wrap-around. This is discovered in a release test. During entropy coding of spectrum the value of "nrg" was too large and after shifting it became negative, resulting in decoder error.
Review URL: http://webrtc-codereview.appspot.com/239016

git-svn-id: http://webrtc.googlecode.com/svn/trunk@862 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.c b/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.c
index dc48529..bcdc229 100644
--- a/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.c
+++ b/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.c
@@ -593,6 +593,7 @@
   if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0)
     return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
 
+
   /* compute inverse AR power spectrum */
   WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16);
 
@@ -669,7 +670,8 @@
   WebRtc_Word32  in_sqrt;
   WebRtc_Word32  newRes;
   WebRtc_Word16  err;
-  int            lft_shft;
+  WebRtc_UWord32  nrg_u32;
+  int            shift_var;
   int          k, n, j, i;
 
 
@@ -704,15 +706,15 @@
 
   /* find AR coefficients */
   /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */
-  lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
+  shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
 
-  if (lft_shft > 0) {
+  if (shift_var > 0) {
     for (k=0; k<AR_ORDER+1; k++) {
-      CorrQ7_norm[k] = CorrQ7[k] << lft_shft;
+      CorrQ7_norm[k] = CorrQ7[k] << shift_var;
     }
   } else {
     for (k=0; k<AR_ORDER+1; k++) {
-      CorrQ7_norm[k] = CorrQ7[k] >> (-lft_shft);
+      CorrQ7_norm[k] = CorrQ7[k] >> (-shift_var);
     }
   }
 
@@ -735,12 +737,19 @@
       nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[n-j] * ARCoefQ12[n] + 256) >> 9) + 4 ) >> 3;
     }
   }
-  if (lft_shft > 0) {
-    nrg >>= lft_shft;
+
+  nrg_u32 = (WebRtc_UWord32)nrg;
+  if (shift_var > 0) {
+    nrg_u32 = nrg_u32 >> shift_var;
   } else {
-    nrg <<= -lft_shft;
+    nrg_u32 = nrg_u32 << (-shift_var);
   }
 
+  if (nrg_u32 > 0x7FFFFFFF)
+    nrg = 0x7FFFFFFF;
+  else
+    nrg = (WebRtc_Word32)nrg_u32;
+
   gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg);  /* also shifts 31 bits to the left! */
 
   /* quantize & code gain2_Q10 */
@@ -826,7 +835,8 @@
   WebRtc_Word32  in_sqrt;
   WebRtc_Word32  newRes;
   WebRtc_Word16  err;
-  int            lft_shft;
+  WebRtc_UWord32 nrg_u32;
+  int            shift_var;
   int          k, n, j, i;
 
   /* create dither_float signal */
@@ -863,15 +873,15 @@
   /* find AR coefficients
      number of bit shifts to 14-bit normalize CorrQ7[0]
      (leaving room for sign) */
-  lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
+  shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
 
-  if (lft_shft > 0) {
+  if (shift_var > 0) {
     for (k=0; k<AR_ORDER+1; k++) {
-      CorrQ7_norm[k] = CorrQ7[k] << lft_shft;
+      CorrQ7_norm[k] = CorrQ7[k] << shift_var;
     }
   } else {
     for (k=0; k<AR_ORDER+1; k++) {
-      CorrQ7_norm[k] = CorrQ7[k] >> (-lft_shft);
+      CorrQ7_norm[k] = CorrQ7[k] >> (-shift_var);
     }
   }
 
@@ -896,12 +906,18 @@
                                 256) >> 9) + 4 ) >> 3;
     }
   }
-  if (lft_shft > 0) {
-    nrg >>= lft_shft;
+  nrg_u32 = (WebRtc_UWord32)nrg;
+  if (shift_var > 0) {
+    nrg_u32 = nrg_u32 >> shift_var;
   } else {
-    nrg <<= -lft_shft;
+    nrg_u32 = nrg_u32 << (-shift_var);
   }
 
+  if (nrg_u32 > 0x7FFFFFFF)
+    nrg = 0x7FFFFFFF;
+  else
+    nrg = (WebRtc_Word32)nrg_u32;
+
   gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg);  /* also shifts 31 bits to the left! */
 
   /* quantize & code gain2_Q10 */
@@ -967,8 +983,9 @@
   WebRtc_Word32  in_sqrt;
   WebRtc_Word32  newRes;
   WebRtc_Word16  err;
-  int            lft_shft;
+  int            shift_var;
   int          k, n, j, i;
+  WebRtc_UWord32 nrg_u32;
 
   /* create dither_float signal */
   GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES);
@@ -1010,15 +1027,15 @@
 
   /* find AR coefficients */
   /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */
-  lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
+  shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
 
-  if (lft_shft > 0) {
+  if (shift_var > 0) {
     for (k=0; k<AR_ORDER+1; k++) {
-      CorrQ7_norm[k] = CorrQ7[k] << lft_shft;
+      CorrQ7_norm[k] = CorrQ7[k] << shift_var;
     }
   } else {
     for (k=0; k<AR_ORDER+1; k++) {
-      CorrQ7_norm[k] = CorrQ7[k] >> (-lft_shft);
+      CorrQ7_norm[k] = CorrQ7[k] >> (-shift_var);
     }
   }
 
@@ -1028,9 +1045,11 @@
   /* quantize & code RC Coef */
   WebRtcIsac_EncodeRc(RCQ15, streamdata);
 
+
   /* RC -> AR coefficients */
   WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
 
+
   /* compute ARCoef' * Corr * ARCoef in Q19 */
   nrg = 0;
   for (j = 0; j <= AR_ORDER; j++) {
@@ -1041,10 +1060,18 @@
       nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[n-j] * ARCoefQ12[n] + 256) >> 9) + 4 ) >> 3;
     }
   }
-  if (lft_shft > 0) {
-    nrg >>= lft_shft;
+
+  nrg_u32 = (WebRtc_UWord32)nrg;
+  if (shift_var > 0) {
+    nrg_u32 = nrg_u32 >> shift_var;
   } else {
-    nrg <<= -lft_shft;
+    nrg_u32 = nrg_u32 << (-shift_var);
+  }
+
+  if (nrg_u32 > 0x7FFFFFFF) {
+    nrg = 0x7FFFFFFF;
+  } else {
+    nrg = (WebRtc_Word32)nrg_u32;
   }
 
   gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg);  /* also shifts 31 bits to the left! */