Merge 700fcf9a18b206789d2d0f04805a877eaf733e07 on remote branch

Change-Id: I5608ca42b1ddf906cbe608ae3931a6c5b0f24fc8
diff --git a/decoder/ixheaacd_basic_ops32.h b/decoder/ixheaacd_basic_ops32.h
index f9a5299..365bfbe 100644
--- a/decoder/ixheaacd_basic_ops32.h
+++ b/decoder/ixheaacd_basic_ops32.h
@@ -180,11 +180,8 @@
 
   sum = (WORD64)a + (WORD64)b;
 
-  if ((((WORD32)a ^ (WORD32)b) & (WORD32)MIN_32) == 0) {
-    if (((WORD32)sum ^ (WORD32)a) & (WORD32)MIN_32) {
-      sum = (a < 0) ? MIN_32 : MAX_32;
-    }
-  }
+  if (sum >= MAX_32) return MAX_32;
+  if (sum <= MIN_32) return MIN_32;
 
   return (WORD32)sum;
 }
@@ -212,11 +209,8 @@
 
   diff = (WORD64)a - (WORD64)b;
 
-  if ((((WORD32)a ^ (WORD32)b) & (WORD32)MIN_32) != 0) {
-    if (((WORD32)diff ^ (WORD32)a) & (WORD32)MIN_32) {
-      diff = (a < 0L) ? MIN_32 : MAX_32;
-    }
-  }
+  if (diff >= MAX_32) return MAX_32;
+  if (diff <= MIN_32) return MIN_32;
 
   return (WORD32)diff;
 }
diff --git a/decoder/ixheaacd_constants.h b/decoder/ixheaacd_constants.h
index a3c2675..3ac0065 100644
--- a/decoder/ixheaacd_constants.h
+++ b/decoder/ixheaacd_constants.h
@@ -63,6 +63,9 @@
 #define MAX_16 (WORD16)0x7fff
 #define MIN_16 (WORD16)0x8000
 
+#define MAX_24 (WORD32)0x007fffff
+#define MIN_24 (WORD32)0xff800000
+
 #define NULLPTR ((VOID *)0)
 
 #define IT_NULL ((VOID *)0)
diff --git a/decoder/ixheaacd_decode_main.c b/decoder/ixheaacd_decode_main.c
index 234178b..7ee1bcd 100644
--- a/decoder/ixheaacd_decode_main.c
+++ b/decoder/ixheaacd_decode_main.c
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "ixheaacd_type_def.h"
+#include "ixheaacd_constants.h"
 #include "ixheaacd_error_standards.h"
 #include "ixheaacd_memory_standards.h"
 #include "ixheaacd_sbrdecsettings.h"
@@ -69,7 +70,7 @@
                           WORD32 *out_bytes, WORD32 num_channel_out) {
   WORD32 num;
   WORD32 i;
-  WORD64 write_local;
+  FLOAT32 sample;
 
   WORD16 *out_buf = (WORD16 *)outbuffer;
 
@@ -77,31 +78,30 @@
 
   if (pcmsize == 16) {
     for (i = 0; i < num; i++) {
-      write_local =
-          ((WORD64)(out_samples[i % num_channel_out][i / num_channel_out]));
+      sample = (out_samples[i % num_channel_out][i / num_channel_out]);
 
-      if (write_local > 32767) {
-        write_local = 32767;
+      if (sample > MAX_16) {
+        sample = MAX_16;
+      } else if (sample < MIN_16) {
+        sample = MIN_16;
       }
-      if (write_local < -32768) {
-        write_local = -32768;
-      }
-      out_buf[i] = (WORD16)write_local;
+      out_buf[i] = (WORD16)sample;
     }
 
     *out_bytes = num * sizeof(WORD16);
   } else {
     WORD8 *out_24bit = (WORD8 *)out_buf;
     for (i = 0; i < num; i++) {
-      write_local = ((WORD64)(
-          out_samples[i % num_channel_out][i / num_channel_out] * 256));
+      WORD32 write_local;
+      sample = (out_samples[i % num_channel_out][i / num_channel_out] * 256);
 
-      if (write_local > 8388607) {
-        write_local = 8388607;
+      if (sample > MAX_24) {
+        sample = MAX_24;
+      } else if (sample < MIN_24) {
+        sample = MIN_24;
       }
-      if (write_local < -8388608) {
-        write_local = -8388608;
-      }
+      write_local = (WORD32)sample;
+
       *out_24bit++ = (WORD32)write_local & 0xff;
       *out_24bit++ = ((WORD32)write_local >> 8) & 0xff;
       *out_24bit++ = ((WORD32)write_local >> 16) & 0xff;
diff --git a/decoder/ixheaacd_sbr_dec.c b/decoder/ixheaacd_sbr_dec.c
index 684b69d..a8ac0b6 100644
--- a/decoder/ixheaacd_sbr_dec.c
+++ b/decoder/ixheaacd_sbr_dec.c
@@ -450,26 +450,6 @@
     ia_sbr_frame_info_data_struct *ptr_frame_data, WORD32 apply_processing,
     FLOAT32 **qmf_buf_real, FLOAT32 **qmf_buf_imag, WORD32 stereo_config_idx,
     ia_sbr_tables_struct *sbr_tables_ptr, WORD32 mps_sbr_flag, WORD32 ch_fac) {
-  WORD32 i, k, p1;
-  WORD32 *ptr_filt_states;
-  WORD32 *ptr_filt_states_1;
-  WORD32 *ptr_filt_states_2;
-  WORD32 *filter_l;
-  WORD32 *ploc_qmf_buf_real;
-  WORD32 *ploc_qmf_buf_imag;
-  WORD32 out_scalefactor;
-  WORD32 sixty4;
-  WORD32 no_synthesis_channels;
-  WORD32 ixheaacd_drc_offset;
-  FLOAT32 *syn_buffer;
-  WORD32 *local_qmf_buffer = ptr_sbr_dec->sbr_scratch_local;
-  WORD32 *time_out = &(ptr_sbr_dec->sbr_scratch_local[128]);
-
-  ia_sbr_qmf_filter_bank_struct *qmf_bank =
-      &ptr_sbr_dec->str_synthesis_qmf_bank;
-  ia_qmf_dec_tables_struct *qmf_dec_tables_ptr =
-      sbr_tables_ptr->qmf_dec_tables_ptr;
-
   if (!mps_sbr_flag) {
     ixheaacd_esbr_synthesis_regrp(&qmf_buf_real[0][0], &qmf_buf_imag[0][0],
                                   ptr_sbr_dec, ptr_frame_data, ptr_header_data,
@@ -479,74 +459,94 @@
                                       ptr_sbr_dec, stereo_config_idx);
   }
 
-  out_scalefactor = 5;
-  qmf_bank->no_channels = 64;
-  qmf_bank->esbr_cos_twiddle =
-      (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l64;
-  qmf_bank->esbr_alt_sin_twiddle =
-      (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l64;
+  if (stereo_config_idx <= 0) {
+    WORD32 i, k, p1;
+    WORD32 *ptr_filt_states;
+    WORD32 *ptr_filt_states_1;
+    WORD32 *ptr_filt_states_2;
+    WORD32 *filter_l;
+    WORD32 *ploc_qmf_buf_real;
+    WORD32 *ploc_qmf_buf_imag;
+    WORD32 out_scalefactor;
+    WORD32 sixty4;
+    WORD32 no_synthesis_channels;
+    WORD32 ixheaacd_drc_offset;
+    FLOAT32 *syn_buffer;
+    WORD32 *local_qmf_buffer = ptr_sbr_dec->sbr_scratch_local;
+    WORD32 *time_out = &(ptr_sbr_dec->sbr_scratch_local[128]);
+    ia_sbr_qmf_filter_bank_struct *qmf_bank =
+        &ptr_sbr_dec->str_synthesis_qmf_bank;
+    ia_qmf_dec_tables_struct *qmf_dec_tables_ptr =
+        sbr_tables_ptr->qmf_dec_tables_ptr;
+    out_scalefactor = 5;
+    qmf_bank->no_channels = 64;
+    qmf_bank->esbr_cos_twiddle =
+        (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l64;
+    qmf_bank->esbr_alt_sin_twiddle =
+        (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l64;
 
-  qmf_bank->filter_pos_syn_32 +=
-      qmf_dec_tables_ptr->esbr_qmf_c - qmf_bank->p_filter_32;
-  qmf_bank->p_filter_32 = qmf_dec_tables_ptr->esbr_qmf_c;
+    qmf_bank->filter_pos_syn_32 +=
+        qmf_dec_tables_ptr->esbr_qmf_c - qmf_bank->p_filter_32;
+    qmf_bank->p_filter_32 = qmf_dec_tables_ptr->esbr_qmf_c;
 
-  sixty4 = NO_SYNTHESIS_CHANNELS;
+    sixty4 = NO_SYNTHESIS_CHANNELS;
 
-  ptr_filt_states = qmf_bank->filter_states_32;
+    ptr_filt_states = qmf_bank->filter_states_32;
 
-  no_synthesis_channels = qmf_bank->no_channels;
-  ptr_filt_states_1 = &ptr_filt_states[0];
-  ptr_filt_states_2 = ptr_filt_states_1 + no_synthesis_channels;
+    no_synthesis_channels = qmf_bank->no_channels;
+    ptr_filt_states_1 = &ptr_filt_states[0];
+    ptr_filt_states_2 = ptr_filt_states_1 + no_synthesis_channels;
 
-  filter_l = qmf_bank->filter_pos_syn_32;
+    filter_l = qmf_bank->filter_pos_syn_32;
 
-  p1 = 0;
+    p1 = 0;
 
-  ixheaacd_drc_offset = qmf_bank->ixheaacd_drc_offset;
+    ixheaacd_drc_offset = qmf_bank->ixheaacd_drc_offset;
 
-  for (i = 0; i < ptr_sbr_dec->str_codec_qmf_bank.num_time_slots; i++) {
-    for (k = 0; k < 64; k++) {
-      local_qmf_buffer[k + 0] = (WORD32)(qmf_buf_real[i][k] * 64);
-      local_qmf_buffer[k + 64] = (WORD32)(qmf_buf_imag[i][k] * 64);
-    }
-    ploc_qmf_buf_real = local_qmf_buffer;
-    ploc_qmf_buf_imag = local_qmf_buffer + 64;
+    for (i = 0; i < ptr_sbr_dec->str_codec_qmf_bank.num_time_slots; i++) {
+      for (k = 0; k < 64; k++) {
+        local_qmf_buffer[k + 0] = (WORD32)(qmf_buf_real[i][k] * 64);
+        local_qmf_buffer[k + 64] = (WORD32)(qmf_buf_imag[i][k] * 64);
+      }
+      ploc_qmf_buf_real = local_qmf_buffer;
+      ploc_qmf_buf_imag = local_qmf_buffer + 64;
 
-    ixheaacd_esbr_inv_modulation(ploc_qmf_buf_real,
-                                 &ptr_sbr_dec->str_synthesis_qmf_bank,
-                                 sbr_tables_ptr->qmf_dec_tables_ptr);
+      ixheaacd_esbr_inv_modulation(ploc_qmf_buf_real,
+                                   &ptr_sbr_dec->str_synthesis_qmf_bank,
+                                   sbr_tables_ptr->qmf_dec_tables_ptr);
 
-    ixheaacd_shiftrountine_with_rnd_hq(ploc_qmf_buf_real, ploc_qmf_buf_imag,
-                                       &ptr_filt_states[ixheaacd_drc_offset],
-                                       no_synthesis_channels,
-                                       out_scalefactor + 1);
+      ixheaacd_shiftrountine_with_rnd_hq(ploc_qmf_buf_real, ploc_qmf_buf_imag,
+                                         &ptr_filt_states[ixheaacd_drc_offset],
+                                         no_synthesis_channels,
+                                         out_scalefactor + 1);
 
-    ixheaacd_esbr_qmfsyn64_winadd(ptr_filt_states_1, ptr_filt_states_2,
-                                  filter_l, &time_out[0], ch_fac);
+      ixheaacd_esbr_qmfsyn64_winadd(ptr_filt_states_1, ptr_filt_states_2,
+                                    filter_l, &time_out[0], ch_fac);
 
-    syn_buffer = ptr_sbr_dec->time_sample_buf + i * 64;
-    for (k = 0; k < 64; k++) {
-      syn_buffer[k] = (FLOAT32)time_out[k] / (1 << 16);
+      syn_buffer = ptr_sbr_dec->time_sample_buf + i * 64;
+      for (k = 0; k < 64; k++) {
+        syn_buffer[k] = (FLOAT32)time_out[k] / (1 << 16);
+      }
+
+      ptr_filt_states_1 += sixty4;
+      ptr_filt_states_2 -= sixty4;
+      sixty4 = -sixty4;
+      ixheaacd_drc_offset -= 128;
+
+      if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 1280;
+
+      filter_l += 64;
+
+      if (filter_l == qmf_bank->p_filter_32 + 640)
+        filter_l = (WORD32 *)qmf_bank->p_filter_32;
+
+      p1 += no_synthesis_channels;
     }
 
-    ptr_filt_states_1 += sixty4;
-    ptr_filt_states_2 -= sixty4;
-    sixty4 = -sixty4;
-    ixheaacd_drc_offset -= 128;
-
-    if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 1280;
-
-    filter_l += 64;
-
-    if (filter_l == qmf_bank->p_filter_32 + 640)
-      filter_l = (WORD32 *)qmf_bank->p_filter_32;
-
-    p1 += no_synthesis_channels;
+    qmf_bank->filter_pos_syn_32 = filter_l;
+    qmf_bank->ixheaacd_drc_offset = ixheaacd_drc_offset;
   }
 
-  qmf_bank->filter_pos_syn_32 = filter_l;
-  qmf_bank->ixheaacd_drc_offset = ixheaacd_drc_offset;
-
   if (!mps_sbr_flag) ptr_frame_data->reset_flag = 0;
 
   if (apply_processing && !mps_sbr_flag) {