Snap for 15047726 from 5e89d3abe53ab5fd216ef8d128c02649ef64afbf to 26Q2-release

Change-Id: I9bb4cdd3517b05cc2d7b2f4323d6474940fec7ea
diff --git a/xhe-aac/aacfastenc/src/cplxpred_stereo.c b/xhe-aac/aacfastenc/src/cplxpred_stereo.c
index ce3e4d2..de53972 100644
--- a/xhe-aac/aacfastenc/src/cplxpred_stereo.c
+++ b/xhe-aac/aacfastenc/src/cplxpred_stereo.c
@@ -238,6 +238,17 @@
   return covarianceMidSide / (energyDmxRe + FLT_MIN);
 }
 
+static int limitCoef(int coef) {
+  const int limit = DELTA_LIMIT / 2;
+  if (coef > limit) {
+    coef = limit;
+  }
+  if (coef < -limit) {
+    coef = -limit;
+  }
+  return coef;
+}
+
 static int iisaacfenc_rdOptimizeCplxPred(const int sfbCnt,
                                          const int sfbPerGroup,
                                          const int maxSfbPerGroup,
@@ -410,6 +421,8 @@
           tmpCoeffIm = predCoeffImQ[sfb];
           predCoeffReQ[sfb] = prevBandCoeffReQ + deltaFreqRe[predBand];
           predCoeffImQ[sfb] = prevBandCoeffImQ + deltaFreqIm[predBand];
+          predCoeffReQ[sfb] = limitCoef(predCoeffReQ[sfb]);
+          predCoeffImQ[sfb] = limitCoef(predCoeffImQ[sfb]);
           predBand++;
           prevBandCoeffReQ = predCoeffReQ[sfb];
           prevBandCoeffImQ = predCoeffImQ[sfb];
@@ -438,6 +451,8 @@
           tmpCoeffIm = predCoeffImQ[sfb];
           predCoeffReQ[sfb] = predCoeffPrevReQ[sfb] + deltaTimeRe[predBand];
           predCoeffImQ[sfb] = predCoeffPrevImQ[sfb] + deltaTimeIm[predBand];
+          predCoeffReQ[sfb] = limitCoef(predCoeffReQ[sfb]);
+          predCoeffImQ[sfb] = limitCoef(predCoeffImQ[sfb]);
           predBand++;
 
           if ((tmpCoeffRe != predCoeffReQ[sfb]) || (tmpCoeffIm != predCoeffImQ[sfb])) {
diff --git a/xhe-aac/aacfastenc/src/unified_stereo_psych.c b/xhe-aac/aacfastenc/src/unified_stereo_psych.c
index f680440..fd763f2 100644
--- a/xhe-aac/aacfastenc/src/unified_stereo_psych.c
+++ b/xhe-aac/aacfastenc/src/unified_stereo_psych.c
@@ -106,6 +106,9 @@
 #include "unified_stereo_psych.h"
 #include "interface.h"
 
+#define LS_TRANS ((FRAME_LEN_LONG - FRAME_LEN_SHORT) / 2)
+#define N_TIME_STEPS 4
+
 void iisaacfenc_UniStePsyProcessing(
     float *sfbThresholdLeft,
     float *sfbThresholdRight,
@@ -144,102 +147,105 @@
     const int maxSfbPerGroup,
     const int *groupLen,
     float uniStePredGainSfb[MAX_SFB]) {
-  int i;
-  int k;
-  float paramBandBorders[28 + 1];
-  int sfb;
-  int sfboffs;
-  float umxMatSfbRe[MAX_SFB][4];
-  float umxMatSfbIm[MAX_SFB][4];
-
   if (hUniSte == 0) {
-    for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) {
-      for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) {
-        uniStePredGainSfb[sfb + sfboffs] = 1.0f;
-      }
-    }
+    setFLOAT(1.0f, uniStePredGainSfb, sfbCnt);
+    return;
+  }
+
+  int sfbOffset;
+  int sfb;
+
+  float umxMatSfbRe[MAX_SFB][N_TIME_STEPS];
+  float umxMatSfbIm[MAX_SFB][N_TIME_STEPS];
+  setFLOAT(0.0f, (float *)umxMatSfbRe, MAX_SFB * N_TIME_STEPS);
+  setFLOAT(0.0f, (float *)umxMatSfbIm, MAX_SFB * N_TIME_STEPS);
+
+  const float *MPSBandBorders;
+  int currMPSBandIdx;
+  if (windowSequence == SHORT_WINDOW) {
+    MPSBandBorders = hUniSte->paramBandBordersShort;
   } else {
-    int timeSlot;
-    static const int LS_TRANS = ((FRAME_LEN_LONG - FRAME_LEN_SHORT) / 2);
-    int pos;
-    int groupAcc = 0;
+    MPSBandBorders = hUniSte->paramBandBordersLong;
+  }
 
-    if (windowSequence == SHORT_WINDOW) {
-      memcpy(paramBandBorders, hUniSte->paramBandBordersShort, (hUniSte->nParamBands + 1) * sizeof(float));
-    } else {
-      memcpy(paramBandBorders, hUniSte->paramBandBordersLong, (hUniSte->nParamBands + 1) * sizeof(float));
-    }
+  assert(FRAME_LEN_LONG % 64 == 0 && FRAME_LEN_SHORT % 64 == 0);
+  int windowCenterIdx = 0;
+  int shortWindowIdx = 0;
+  switch (windowSequence) {
+    case LONG_WINDOW:
+    case STOPSTART_WINDOW:
+      windowCenterIdx = (2 * FRAME_LEN_LONG) / 64;
+      break;
+    case START_WINDOW:
+    case STOP_WINDOW:
+      windowCenterIdx = (FRAME_LEN_LONG + LS_TRANS) / 64;
+      break;
+    case SHORT_WINDOW:
+      windowCenterIdx = (FRAME_LEN_LONG + 64) / 64;
+      break;
+    default:
+      assert(0);
+      break;
+  }
 
-    switch (windowSequence) {
-      case LONG_WINDOW:
-      case STOPSTART_WINDOW:
-        timeSlot = (2 * FRAME_LEN_LONG) / 64;
-        break;
-      case START_WINDOW:
-      case STOP_WINDOW:
-        timeSlot = (FRAME_LEN_LONG + LS_TRANS) / 64;
-        break;
-      default:
-        timeSlot = -1;
-        break;
-    }
+  int currMPSBandBorder = 0;
+  for (sfbOffset = 0; sfbOffset < sfbCnt; sfbOffset += sfbPerGroup) {
+    for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+      assert(sfbOffset + sfb < MAX_SFB);
 
-    for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) {
-      if (windowSequence == SHORT_WINDOW) {
-        timeSlot = (FRAME_LEN_LONG + 64 + groupAcc * FRAME_LEN_SHORT) / 64;
+      uniStePredGainSfb[sfbOffset + sfb] = 0.0f;
+
+      const int sfbStartLine = psyConf->sfbOffset[sfb];
+      const int sfbEndLine = min(psyConf->lowpassLine, psyConf->sfbOffset[sfb + 1]);
+
+      int MPSStartBand = -1;
+      int MPSEndBand = -1;
+      for (currMPSBandIdx = 0; currMPSBandIdx < hUniSte->nParamBands; currMPSBandIdx++) {
+        if (MPSBandBorders[currMPSBandIdx] > sfbStartLine && MPSStartBand == -1) {
+          MPSStartBand = currMPSBandIdx - 1;
+        }
+        if (MPSBandBorders[currMPSBandIdx] >= sfbEndLine && MPSStartBand != -1) {
+          MPSEndBand = currMPSBandIdx - 1;
+          break;
+        }
       }
 
-      for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) {
-        int sfbStartLine = psyConf->sfbOffset[sfboffs];
-        int sfbEndLine = min(psyConf->lowpassLine, psyConf->sfbOffset[sfboffs + 1]);
-        int paramBandFirst = -1;
-        int paramBandLast = -1;
-        assert(sfb + sfboffs < MAX_SFB);
+      unsigned int stopCondition = 0;
 
-        for (i = 0; i < hUniSte->nParamBands; i++) {
-          if (paramBandBorders[i] > sfbStartLine) {
-            paramBandFirst = i - 1;
-            break;
-          }
-        }
-
-        for (i = 0; i < hUniSte->nParamBands; i++) {
-          if (paramBandBorders[i] >= sfbEndLine) {
-            paramBandLast = i - 1;
-            break;
-          }
-        }
-
-        if ((paramBandFirst < hUniSte->nResidualBands) &&
-            (paramBandLast >= hUniSte->nResidualBands)) {
-          paramBandBorders[paramBandLast] = (float)sfbEndLine;
-          paramBandLast -= 1;
-        }
-
-        uniStePredGainSfb[sfb + sfboffs] = 0.0f;
-        for (k = 0; k < 4; k++) {
-          umxMatSfbRe[sfb + sfboffs][k] = umxMatSfbIm[sfb + sfboffs][k] = 0.0f;
-        }
-
-        pos = sfbStartLine;
-        for (i = paramBandFirst; i <= paramBandLast; i++) {
-          for (k = 0; k < 4; k++) {
-            umxMatSfbRe[sfb + sfboffs][k] += (min(sfbEndLine, paramBandBorders[i + 1]) - pos) * hUniSte->umxMatRe[timeSlot][i][k] / (sfbEndLine - sfbStartLine);
-            umxMatSfbIm[sfb + sfboffs][k] += (min(sfbEndLine, paramBandBorders[i + 1]) - pos) * hUniSte->umxMatIm[timeSlot][i][k] / (sfbEndLine - sfbStartLine);
-          }
-
-          uniStePredGainSfb[sfb + sfboffs] += (float)pow(10, (hUniSte->cld[timeSlot][i] > 0 ? -hUniSte->cld[timeSlot][i] : hUniSte->cld[timeSlot][i]) * 0.1f) * (min(sfbEndLine, paramBandBorders[i + 1]) - pos) / (sfbEndLine - sfbStartLine);
-
-          pos = (int)paramBandBorders[i + 1];
-        }
-
-        uniStePredGainSfb[sfb + sfboffs] = min(
-            (umxMatSfbRe[sfb + sfboffs][0] * umxMatSfbRe[sfb + sfboffs][0] +
-             umxMatSfbIm[sfb + sfboffs][0] * umxMatSfbIm[sfb + sfboffs][0]),
-            (umxMatSfbRe[sfb + sfboffs][2] * umxMatSfbRe[sfb + sfboffs][2] +
-             umxMatSfbIm[sfb + sfboffs][2] * umxMatSfbIm[sfb + sfboffs][2]));
+      if ((MPSStartBand < hUniSte->nResidualBands) &&
+          (MPSEndBand >= hUniSte->nResidualBands)) {
+        MPSEndBand -= 1;
+        stopCondition = 1;
       }
-      groupAcc += groupLen[sfb / sfbPerGroup];
+
+      currMPSBandBorder = sfbStartLine;
+      int sfbWidth = sfbEndLine - sfbStartLine;
+
+      for (currMPSBandIdx = MPSStartBand; currMPSBandIdx <= MPSEndBand; currMPSBandIdx++) {
+        if (currMPSBandIdx > sfbEndLine && stopCondition) break;
+
+        for (int currTimeStep = 0; currTimeStep < N_TIME_STEPS; currTimeStep++) {
+          umxMatSfbRe[sfbOffset + sfb][currTimeStep] += (min(sfbEndLine, MPSBandBorders[currMPSBandIdx + 1]) - currMPSBandBorder) * hUniSte->umxMatRe[windowCenterIdx][currMPSBandIdx][currTimeStep] / sfbWidth;
+          umxMatSfbIm[sfbOffset + sfb][currTimeStep] += (min(sfbEndLine, MPSBandBorders[currMPSBandIdx + 1]) - currMPSBandBorder) * hUniSte->umxMatIm[windowCenterIdx][currMPSBandIdx][currTimeStep] / sfbWidth;
+        }
+
+        float exponent = 0.0f;
+        if (hUniSte->cld[windowCenterIdx][currMPSBandIdx] > 0) {
+          exponent = -hUniSte->cld[windowCenterIdx][currMPSBandIdx];
+        } else {
+          exponent = hUniSte->cld[windowCenterIdx][currMPSBandIdx] * 0.1f;
+        }
+        exponent *= 0.1f;
+        float factor = (min(sfbEndLine, MPSBandBorders[currMPSBandIdx + 1]) - currMPSBandBorder);
+        uniStePredGainSfb[sfbOffset + sfb] += (float)pow(10, exponent) * factor / sfbWidth;
+
+        currMPSBandBorder = (int)MPSBandBorders[currMPSBandIdx + 1];
+      }
+
+      uniStePredGainSfb[sfbOffset + sfb] = min(
+          (umxMatSfbRe[sfbOffset + sfb][0] * umxMatSfbRe[sfbOffset + sfb][0] + umxMatSfbIm[sfbOffset + sfb][0] * umxMatSfbIm[sfbOffset + sfb][0]),
+          (umxMatSfbRe[sfbOffset + sfb][2] * umxMatSfbRe[sfbOffset + sfb][2] + umxMatSfbIm[sfbOffset + sfb][2] * umxMatSfbIm[sfbOffset + sfb][2]));
     }
+    windowCenterIdx += groupLen[shortWindowIdx++] * FRAME_LEN_SHORT / 64;
   }
 }
diff --git a/xhe-aac/iisDRCGainEncLib/src/iisDRCGainEnc_nodeSetting.c b/xhe-aac/iisDRCGainEncLib/src/iisDRCGainEnc_nodeSetting.c
index dd1a7ba..10cbd5a 100644
--- a/xhe-aac/iisDRCGainEncLib/src/iisDRCGainEnc_nodeSetting.c
+++ b/xhe-aac/iisDRCGainEncLib/src/iisDRCGainEnc_nodeSetting.c
@@ -385,7 +385,8 @@
   for (k = 0; k < hIisDrcGainEnc_params->gainSequenceCount; k++) {
     DrcGainSequence *pDrcGainSequence = &hIisDrcGainEnc_params->pUniDrcGain->pDrcGainSequence[k];
     if (pDrcGainSequence->gainCodingProfile != IISDRCGAINENC_GAINCODINGPROFILE_CONSTANT) {
-      retVal = pFuncSetNodesGeneric(&hIisDrcGainEnc_params->pUniDrcGain->pDrcGainSequence[k], drcGainInputBuffer[k], bIsPrerollFrame, hIisDrcGainEnc_params->frameSize);
+      int bIsPrerollFrame_used = bIsPrerollFrame;
+      retVal = pFuncSetNodesGeneric(&hIisDrcGainEnc_params->pUniDrcGain->pDrcGainSequence[k], drcGainInputBuffer[k], bIsPrerollFrame_used, hIisDrcGainEnc_params->frameSize);
       if (retVal != IISDRCGAINENC_RETURN_NOERROR) return retVal;
 
       if (pDrcGainSequence->fullFrame == 1) {
diff --git a/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGenerator.c b/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGenerator.c
index 7b86f32..f7619ce 100644
--- a/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGenerator.c
+++ b/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGenerator.c
@@ -98,9 +98,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
+#include <iisutillib.h>
 #include "iisDRCGainGenerator.h"
 #include "iisDRCGainGeneratorProcess.h"
-#include "iisDRCGainGeneratorMemManager.h"
 
 const float bs1770IntTimeS = 0.032f;
 
@@ -239,18 +239,18 @@
   }
 
   if (*phIisDRCGainGenParams == NULL) {
-    iisDRCGainGenParams = (IisDRCGainGenParams*)MEM_ALLOC(sizeof(struct T_DRCGAINGEN_PARAMS));
+    iisDRCGainGenParams = (IisDRCGainGenParams*)iisCalloc(1, sizeof(struct T_DRCGAINGEN_PARAMS));
     if (iisDRCGainGenParams == NULL) {
       return -3;
     }
     iisDRCGainGenParams->frameSize = pConfig_drcGainGen->frameSize;
     if (numGainBandSequencesTmp != 0) {
-      iisDRCGainGenParams->iisDRCGainGenParamsInstance = (IisDRCGainGenParamsInstance*)MEM_ALLOC(numGainBandSequencesTmp * sizeof(struct T_DRCGAINGEN_PARAMSINSTANCE));
+      iisDRCGainGenParams->iisDRCGainGenParamsInstance = (IisDRCGainGenParamsInstance*)iisCalloc(numGainBandSequencesTmp, sizeof(struct T_DRCGAINGEN_PARAMSINSTANCE));
     } else {
       iisDRCGainGenParams->iisDRCGainGenParamsInstance = NULL;
     }
     for (k = 0; k < numGainBandSequencesTmp; k++) {
-      iisDRCGainGenParams->iisDRCGainGenParamsInstance[k].channelWeight = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
+      iisDRCGainGenParams->iisDRCGainGenParamsInstance[k].channelWeight = (float*)iisCalloc(maxChannelCount, sizeof(float));
       iisDRCGainGenParams->iisDRCGainGenParamsInstance[k].drcLevelCalculationMode = pConfig_drcGainGen->drcLevelCalculationMode[k];
     }
   }
@@ -265,7 +265,7 @@
   iisDRCGainGenParams->numExtParamsDefined = 0;
 
   if (iisDRCGainGenParams->iisDRCGainGenExtParams == NULL && pConfig_drcGainGen->numExtParams > 0) {
-    iisDRCGainGenParams->iisDRCGainGenExtParams = (IisDRCGainGenExtParams*)MEM_ALLOC(pConfig_drcGainGen->numExtParams * sizeof(struct T_DRCGAINGEN_EXTPARAMS));
+    iisDRCGainGenParams->iisDRCGainGenExtParams = (IisDRCGainGenExtParams*)iisCalloc(pConfig_drcGainGen->numExtParams, sizeof(struct T_DRCGAINGEN_EXTPARAMS));
   }
 
   for (n = 0; n < pConfig_drcGainGen->sequenceCount; n++) {
@@ -328,57 +328,57 @@
   }
 
   if (*phIisDRCGainGenStates == NULL) {
-    iisDRCGainGenStates = (IisDRCGainGenStates*)MEM_ALLOC(sizeof(struct T_DRCGAINGEN_STATES));
+    iisDRCGainGenStates = (IisDRCGainGenStates*)iisCalloc(1, sizeof(struct T_DRCGAINGEN_STATES));
     if (iisDRCGainGenStates == NULL) {
       return -3;
     }
-    iisDRCGainGenStates->iisDRCGainGenStatesInstance = (IisDRCGainGenStatesInstance*)MEM_ALLOC(numGainBandSequencesTmp * sizeof(struct T_DRCGAINGEN_STATESINSTANCE));
-    iisDRCGainGenStates->audioBufferApplyDelayPointer = (float**)MEM_ALLOC(maxChannelCount * sizeof(float*));
+    iisDRCGainGenStates->iisDRCGainGenStatesInstance = (IisDRCGainGenStatesInstance*)iisCalloc(numGainBandSequencesTmp, sizeof(struct T_DRCGAINGEN_STATESINSTANCE));
+    iisDRCGainGenStates->audioBufferApplyDelayPointer = (float**)iisCalloc(maxChannelCount, sizeof(float*));
 
     for (k = 0; k < numGainBandSequencesTmp; k++) {
-      iisDRCGainGenStates->iisDRCGainGenStatesInstance[k].levelDb = (float*)MEM_ALLOC(pConfig_drcGainGen->frameSize * sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenStatesInstance[k].levelDb = (float*)iisCalloc(pConfig_drcGainGen->frameSize, sizeof(float));
 
-      iisDRCGainGenStates->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.int_y1 = (float*)MEM_ALLOC(numChannelsTmp[k] * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.ySum = (float*)MEM_ALLOC(pConfig_drcGainGen->frameSize * sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.int_y1 = (float*)iisCalloc(numChannelsTmp[k], sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.ySum = (float*)iisCalloc(pConfig_drcGainGen->frameSize, sizeof(float));
     }
   }
 
   {
-    iisDRCGainGenParams->iisDRCGainGenLevelCalcParams_BS1770Filter = (IisDRCGainGenLevelCalcParams_BS1770Filter*)MEM_ALLOC(numLevelEstimInstances * sizeof(struct T_DRCGAINGEN_PARAMSINSTANCE));
-    iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter = (IisDRCGainGenLevelCalcStates_BS1770Filter*)MEM_ALLOC(numLevelEstimInstances * sizeof(struct T_DRCGAINGENSTATE_LEVELCALCBS1770FILTER));
+    iisDRCGainGenParams->iisDRCGainGenLevelCalcParams_BS1770Filter = (IisDRCGainGenLevelCalcParams_BS1770Filter*)iisCalloc(numLevelEstimInstances, sizeof(struct T_DRCGAINGEN_PARAMSINSTANCE));
+    iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter = (IisDRCGainGenLevelCalcStates_BS1770Filter*)iisCalloc(numLevelEstimInstances, sizeof(struct T_DRCGAINGENSTATE_LEVELCALCBS1770FILTER));
 
-    iisDRCGainGenStates->audioWithGainApplied = (float**)MEM_ALLOC(maxChannelCount * sizeof(float*));
+    iisDRCGainGenStates->audioWithGainApplied = (float**)iisCalloc(maxChannelCount, sizeof(float*));
     for (m = 0; m < maxChannelCount; m++) {
-      iisDRCGainGenStates->audioWithGainApplied[m] = (float*)MEM_ALLOC(pConfig_drcGainGen->frameSize * sizeof(float));
+      iisDRCGainGenStates->audioWithGainApplied[m] = (float*)iisCalloc(pConfig_drcGainGen->frameSize, sizeof(float));
     }
     for (k = 0; k < numLevelEstimInstances; k++) {
       iisDRCGainGenParams->iisDRCGainGenLevelCalcParams_BS1770Filter[k].frameSize = pConfig_drcGainGen->frameSize;
       iisDRCGainGenParams->iisDRCGainGenLevelCalcParams_BS1770Filter[k].numChannels = numInputChannelsLevEstim[k];
 
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x1 = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x2 = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y1 = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y2 = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x1 = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x2 = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y1 = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y2 = (float*)MEM_ALLOC(maxChannelCount * sizeof(float));
-      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare = (float**)MEM_ALLOC(maxChannelCount * sizeof(float*));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x1 = (float*)iisCalloc(maxChannelCount, sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x2 = (float*)iisCalloc(maxChannelCount, sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y1 = (float*)iisCalloc(maxChannelCount, sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y2 = (float*)iisCalloc(maxChannelCount, sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x1 = (float*)iisCalloc(maxChannelCount, sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x2 = (float*)iisCalloc(maxChannelCount, sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y1 = (float*)iisCalloc(maxChannelCount, sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y2 = (float*)iisCalloc(maxChannelCount, sizeof(float));
+      iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare = (float**)iisCalloc(maxChannelCount, sizeof(float*));
       for (m = 0; m < maxChannelCount; m++) {
-        iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare[m] = (float*)MEM_ALLOC((pConfig_drcGainGen->frameSize + iisDRCGainGenParams->maxLookaheadSamples) * sizeof(float));
+        iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare[m] = (float*)iisCalloc((pConfig_drcGainGen->frameSize + iisDRCGainGenParams->maxLookaheadSamples), sizeof(float));
       }
 
       iisDRCGainGenParams->iisDRCGainGenLevelCalcParams_BS1770Filter[k].applyExternalDrcGains = applyExternalDrcGains[k];
       if (applyExternalDrcGains[k]) {
-        iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].externalGain = (float*)MEM_ALLOC((pConfig_drcGainGen->frameSize + iisDRCGainGenParams->maxLookaheadSamples) * sizeof(float));
+        iisDRCGainGenStates->iisDRCGainGenLevelCalcStates_BS1770Filter[k].externalGain = (float*)iisCalloc((pConfig_drcGainGen->frameSize + iisDRCGainGenParams->maxLookaheadSamples), sizeof(float));
       }
     }
   }
 
   if (pConfig_drcGainGen->useProcessWrapper) {
-    iisDRCGainGenStates->audioInWithLookahead = (float**)MEM_ALLOC(maxChannelCount * sizeof(float*));
+    iisDRCGainGenStates->audioInWithLookahead = (float**)iisCalloc(maxChannelCount, sizeof(float*));
     for (m = 0; m < maxChannelCount; m++) {
-      iisDRCGainGenStates->audioInWithLookahead[m] = (float*)MEM_ALLOC((pConfig_drcGainGen->frameSize + iisDRCGainGenParams->maxLookaheadSamples) * sizeof(float));
+      iisDRCGainGenStates->audioInWithLookahead[m] = (float*)iisCalloc((pConfig_drcGainGen->frameSize + iisDRCGainGenParams->maxLookaheadSamples), sizeof(float));
     }
   }
 
@@ -842,108 +842,108 @@
   if (*phIisDRCGainGenStates != NULL) {
     for (k = 0; k < (*phIisDRCGainGenParams)->numGainBandSequences; k++) {
       if ((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].levelDb != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].levelDb);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].levelDb);
         (*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].levelDb = NULL;
       }
 
       if ((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.int_y1 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.int_y1);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.int_y1);
         (*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.int_y1 = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.ySum != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.ySum);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.ySum);
         (*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance[k].iisDRCGainGenLevelCalcStates_BS1770Int.ySum = NULL;
       }
     }
 
     for (k = 0; k < (*phIisDRCGainGenParams)->numLevelEstimInstances; k++) {
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x1 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x1);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x1);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x1 = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x2 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x2);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x2);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_x2 = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y1 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y1);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y1);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y1 = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y2 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y2);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y2);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].pre_y2 = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x1 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x1);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x1);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x1 = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x2 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x2);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x2);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_x2 = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y1 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y1);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y1);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y1 = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y2 != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y2);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y2);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].rlb_y2 = NULL;
       }
       for (m = 0; m < (*phIisDRCGainGenParams)->maxChannelCount; m++) {
         if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare[m] != NULL) {
-          MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare[m]);
+          iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare[m]);
           (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare[m] = NULL;
         }
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].xSquare = NULL;
       }
       if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].externalGain != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].externalGain);
+        iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].externalGain);
         (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter[k].externalGain = NULL;
       }
     }
 
     for (m = 0; m < (*phIisDRCGainGenParams)->maxChannelCount; m++) {
       if ((*phIisDRCGainGenStates)->audioWithGainApplied[m] != NULL) {
-        MEM_FREE((*phIisDRCGainGenStates)->audioWithGainApplied[m]);
+        iisFree((*phIisDRCGainGenStates)->audioWithGainApplied[m]);
         (*phIisDRCGainGenStates)->audioWithGainApplied[m] = NULL;
       }
     }
     if ((*phIisDRCGainGenStates)->audioWithGainApplied != NULL) {
-      MEM_FREE((*phIisDRCGainGenStates)->audioWithGainApplied);
+      iisFree((*phIisDRCGainGenStates)->audioWithGainApplied);
       (*phIisDRCGainGenStates)->audioWithGainApplied = NULL;
     }
 
     if ((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter != NULL) {
-      MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter);
+      iisFree((*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter);
       (*phIisDRCGainGenStates)->iisDRCGainGenLevelCalcStates_BS1770Filter = NULL;
     }
 
     if ((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance != NULL) {
-      MEM_FREE((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance);
+      iisFree((*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance);
       (*phIisDRCGainGenStates)->iisDRCGainGenStatesInstance = NULL;
     }
     if ((*phIisDRCGainGenStates)->audioBufferApplyDelayPointer != NULL) {
-      MEM_FREE((*phIisDRCGainGenStates)->audioBufferApplyDelayPointer);
+      iisFree((*phIisDRCGainGenStates)->audioBufferApplyDelayPointer);
       (*phIisDRCGainGenStates)->audioBufferApplyDelayPointer = NULL;
     }
 
     if ((*phIisDRCGainGenStates)->audioInWithLookahead != NULL) {
       for (m = 0; m < (*phIisDRCGainGenParams)->maxChannelCount; m++) {
         if ((*phIisDRCGainGenStates)->audioInWithLookahead[m] != NULL) {
-          MEM_FREE((*phIisDRCGainGenStates)->audioInWithLookahead[m]);
+          iisFree((*phIisDRCGainGenStates)->audioInWithLookahead[m]);
           (*phIisDRCGainGenStates)->audioInWithLookahead[m] = NULL;
         }
       }
 
-      MEM_FREE((*phIisDRCGainGenStates)->audioInWithLookahead);
+      iisFree((*phIisDRCGainGenStates)->audioInWithLookahead);
       (*phIisDRCGainGenStates)->audioInWithLookahead = NULL;
     }
 
     if ((*phIisDRCGainGenStates) != NULL) {
-      MEM_FREE(*phIisDRCGainGenStates);
+      iisFree(*phIisDRCGainGenStates);
       *phIisDRCGainGenStates = NULL;
     }
   }
@@ -952,26 +952,26 @@
     for (k = 0; k < (*phIisDRCGainGenParams)->numGainBandSequences; k++) {
       if ((*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance != NULL) {
         if ((*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance[k].channelWeight != NULL) {
-          MEM_FREE((*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance[k].channelWeight);
+          iisFree((*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance[k].channelWeight);
           (*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance[k].channelWeight = NULL;
         }
       }
     }
 
     if ((*phIisDRCGainGenParams)->iisDRCGainGenLevelCalcParams_BS1770Filter != NULL) {
-      MEM_FREE((*phIisDRCGainGenParams)->iisDRCGainGenLevelCalcParams_BS1770Filter);
+      iisFree((*phIisDRCGainGenParams)->iisDRCGainGenLevelCalcParams_BS1770Filter);
       (*phIisDRCGainGenParams)->iisDRCGainGenLevelCalcParams_BS1770Filter = NULL;
     }
     if ((*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance != NULL) {
-      MEM_FREE((*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance);
+      iisFree((*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance);
       (*phIisDRCGainGenParams)->iisDRCGainGenParamsInstance = NULL;
     }
     if ((*phIisDRCGainGenParams)->iisDRCGainGenExtParams != NULL) {
-      MEM_FREE((*phIisDRCGainGenParams)->iisDRCGainGenExtParams);
+      iisFree((*phIisDRCGainGenParams)->iisDRCGainGenExtParams);
       (*phIisDRCGainGenParams)->iisDRCGainGenExtParams = NULL;
     }
     if (*phIisDRCGainGenParams != NULL) {
-      MEM_FREE(*phIisDRCGainGenParams);
+      iisFree(*phIisDRCGainGenParams);
       *phIisDRCGainGenParams = NULL;
     }
   }
diff --git a/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGeneratorMemManager.c b/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGeneratorMemManager.c
deleted file mode 100644
index c373212..0000000
--- a/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGeneratorMemManager.c
+++ /dev/null
@@ -1,130 +0,0 @@
-
-/* -----------------------------------------------------------------------------
-Software Copyright License for The Fraunhofer FDK Extended High Efficiency AAC
-Encoder Software for Android
-
-© Copyright 1995 - 2025 Fraunhofer-Gesellschaft zur Förderung der angewandten
-Forschung e.V. and Contributors
-All rights reserved.
-
-1.    INTRODUCTION
-
-The Fraunhofer FDK Extended High Efficiency AAC Encoder Software for Android
-("FDK Extended High Efficiency AAC Encoder") is software that implements the
-encoding of digital audio according to the MPEG-D Unified Speech and Audio
-Coding (USAC) standard and MPEG-D Dynamic Range Control (DRC) standard. This FDK
-Extended High Efficiency AAC Encoder Software is intended to be used on a wide
-variety of Android devices. It is technically not suited to encode content for
-digital radio broadcasting services, including DRM and similar standards.
-
-Patent licenses for necessary patent claims for the FDK Extended High Efficiency
-AAC Encoder Software (including those of Fraunhofer), for the use in commercial
-products and services, may be obtained from the respective patent owners
-individually and/or from Via Licensing Alliance (www.via-la.com).
-
-Fraunhofer supports the development of Extended High Efficiency AAC products and
-services by offering additional software, documentation, and technical advice.
-In addition, it operates the xHE-AAC Trademark Program to ease interoperability
-testing of end products. Please visit http://www.xhe-aac.com for more
-information.
-
-2.    COPYRIGHT LICENSE
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted without payment of copyright license fees, provided that you
-satisfy the following conditions:
-
-You must retain the complete text of this software license in redistributions of
-the FDK Extended High Efficiency AAC Encoder Software or your modifications
-thereto in source code form.
-
-You must retain the complete text of this software license in the documentation
-and/or other materials provided with redistributions of the FDK Extended High
-Efficiency AAC Encoder Software or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the
-FDK Extended High Efficiency AAC Encoder Software and your modifications thereto
-to recipients of copies in binary form.
-
-The name of Fraunhofer may not be used to endorse or promote products derived
-from this software without prior written permission.
-
-You may not charge copyright license fees for anyone to use, copy or distribute
-the FDK Extended High Efficiency AAC Encoder Software or your modifications
-thereto.
-
-Your modified versions of the FDK Extended High Efficiency AAC Encoder Software
-must carry prominent notices stating that you changed the software and the date
-of any change. For modified versions of the FDK Extended High Efficiency AAC
-Encoder Software, the term "Fraunhofer FDK Extended High Efficiency AAC Encoder
-Software for Android" must be replaced by the term "Third-Party Modified Version
-of the Fraunhofer FDK Extended High Efficiency AAC Encoder Software for
-Android."
-
-3.    NO PATENT LICENSE
-
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
-limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
-Fraunhofer provides no warranty for patent non-infringement with respect to this
-software. You may use this FDK Extended High Efficiency AAC Encoder Software or
-modifications thereto only for purposes that are authorized by appropriate
-patent licenses.
-
-4.    DISCLAIMER
-
-This FDK Extended High Efficiency AAC Encoder Software is provided by Fraunhofer
-on behalf of the copyright holders and contributors "AS IS" and WITHOUT ANY
-EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied
-warranties of merchantability and fitness for a particular purpose. IN NO EVENT
-SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE for any direct, indirect,
-incidental, special, exemplary, or consequential damages, including but not
-limited to procurement of substitute goods or services; loss of use, data, or
-profits, or business interruption, however caused and on any theory of
-liability, whether in contract, strict liability, or tort (including
-negligence), arising in any way out of the use of this software, even if advised
-of the possibility of such damage.
-
-5.    CONTACT INFORMATION
-
-Fraunhofer Institute for Integrated Circuits IIS
-Attention: Division Audio and Media Technologies - FDK Extended High Efficiency
-AAC Encoder
-Am Wolfsmantel 33
-91058 Erlangen, Germany
-
-www.iis.fraunhofer.de/amm
-amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------ */
-
-#include <string.h>
-
-#include "iisDRCGainGeneratorMemManager.h"
-
-#define USE_UTILLIB
-
-#ifdef USE_UTILLIB
-#include "iisutillib.h"
-#else
-#include <stdlib.h>
-#endif
-
-void *MEM_ALLOC(const unsigned int size) {
-#ifdef USE_UTILLIB
-  char *tmp = NULL;
-  tmp = (void *)iisMalloc(size);
-
-  if (tmp) {
-    memset(tmp, 0, size);
-  }
-  return tmp;
-#else
-  return calloc(1, size);
-#endif
-}
-
-void MEM_FREE(void *ptr) {
-#ifdef USE_UTILLIB
-  iisFree(ptr);
-#else
-  free(ptr);
-#endif
-}
diff --git a/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGeneratorMemManager.h b/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGeneratorMemManager.h
deleted file mode 100644
index 6915516..0000000
--- a/xhe-aac/iisDRCGainGenLib/src/iisDRCGainGeneratorMemManager.h
+++ /dev/null
@@ -1,105 +0,0 @@
-
-/* -----------------------------------------------------------------------------
-Software Copyright License for The Fraunhofer FDK Extended High Efficiency AAC
-Encoder Software for Android
-
-© Copyright 1995 - 2025 Fraunhofer-Gesellschaft zur Förderung der angewandten
-Forschung e.V. and Contributors
-All rights reserved.
-
-1.    INTRODUCTION
-
-The Fraunhofer FDK Extended High Efficiency AAC Encoder Software for Android
-("FDK Extended High Efficiency AAC Encoder") is software that implements the
-encoding of digital audio according to the MPEG-D Unified Speech and Audio
-Coding (USAC) standard and MPEG-D Dynamic Range Control (DRC) standard. This FDK
-Extended High Efficiency AAC Encoder Software is intended to be used on a wide
-variety of Android devices. It is technically not suited to encode content for
-digital radio broadcasting services, including DRM and similar standards.
-
-Patent licenses for necessary patent claims for the FDK Extended High Efficiency
-AAC Encoder Software (including those of Fraunhofer), for the use in commercial
-products and services, may be obtained from the respective patent owners
-individually and/or from Via Licensing Alliance (www.via-la.com).
-
-Fraunhofer supports the development of Extended High Efficiency AAC products and
-services by offering additional software, documentation, and technical advice.
-In addition, it operates the xHE-AAC Trademark Program to ease interoperability
-testing of end products. Please visit http://www.xhe-aac.com for more
-information.
-
-2.    COPYRIGHT LICENSE
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted without payment of copyright license fees, provided that you
-satisfy the following conditions:
-
-You must retain the complete text of this software license in redistributions of
-the FDK Extended High Efficiency AAC Encoder Software or your modifications
-thereto in source code form.
-
-You must retain the complete text of this software license in the documentation
-and/or other materials provided with redistributions of the FDK Extended High
-Efficiency AAC Encoder Software or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the
-FDK Extended High Efficiency AAC Encoder Software and your modifications thereto
-to recipients of copies in binary form.
-
-The name of Fraunhofer may not be used to endorse or promote products derived
-from this software without prior written permission.
-
-You may not charge copyright license fees for anyone to use, copy or distribute
-the FDK Extended High Efficiency AAC Encoder Software or your modifications
-thereto.
-
-Your modified versions of the FDK Extended High Efficiency AAC Encoder Software
-must carry prominent notices stating that you changed the software and the date
-of any change. For modified versions of the FDK Extended High Efficiency AAC
-Encoder Software, the term "Fraunhofer FDK Extended High Efficiency AAC Encoder
-Software for Android" must be replaced by the term "Third-Party Modified Version
-of the Fraunhofer FDK Extended High Efficiency AAC Encoder Software for
-Android."
-
-3.    NO PATENT LICENSE
-
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
-limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
-Fraunhofer provides no warranty for patent non-infringement with respect to this
-software. You may use this FDK Extended High Efficiency AAC Encoder Software or
-modifications thereto only for purposes that are authorized by appropriate
-patent licenses.
-
-4.    DISCLAIMER
-
-This FDK Extended High Efficiency AAC Encoder Software is provided by Fraunhofer
-on behalf of the copyright holders and contributors "AS IS" and WITHOUT ANY
-EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied
-warranties of merchantability and fitness for a particular purpose. IN NO EVENT
-SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE for any direct, indirect,
-incidental, special, exemplary, or consequential damages, including but not
-limited to procurement of substitute goods or services; loss of use, data, or
-profits, or business interruption, however caused and on any theory of
-liability, whether in contract, strict liability, or tort (including
-negligence), arising in any way out of the use of this software, even if advised
-of the possibility of such damage.
-
-5.    CONTACT INFORMATION
-
-Fraunhofer Institute for Integrated Circuits IIS
-Attention: Division Audio and Media Technologies - FDK Extended High Efficiency
-AAC Encoder
-Am Wolfsmantel 33
-91058 Erlangen, Germany
-
-www.iis.fraunhofer.de/amm
-amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------ */
-
-#ifndef IISDRCGAINGENERATORMEMMANAGER_H
-#define IISDRCGAINGENERATORMEMMANAGER_H
-
-void *MEM_ALLOC(const unsigned int size);
-
-void MEM_FREE(void *ptr);
-
-#endif
diff --git a/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib.c b/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib.c
index 3e4e74d..3c90cf2 100644
--- a/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib.c
+++ b/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib.c
@@ -1537,7 +1537,8 @@
 
         if (!isError(retValue)) {
           if (hInstance->hConfig->aot == AUD_OBJ_TYP_USAC) {
-            retValue = iisxHEAACEncLib_extentsionData_usacSetUse(&hInstance->extEleList, XHEAACENCLIB_EXT_ELE_USAC_UNI_DRC, 1, IISXHEAACENCLIB_DEFAULT_LENGTH_UNIDRC, pExtensionConfig, extensionConfigLength, 0);
+            unsigned int defaultLengthUniDrc = IISXHEAACENCLIB_DEFAULT_LENGTH_UNIDRC;
+            retValue = iisxHEAACEncLib_extentsionData_usacSetUse(&hInstance->extEleList, XHEAACENCLIB_EXT_ELE_USAC_UNI_DRC, 1, defaultLengthUniDrc, pExtensionConfig, extensionConfigLength, 0);
           } else {
             retValue = iisxHEAACEncLib_extensionData_generalSetUse(&hInstance->extEleList, hInstance->hConfig, XHEAACENCLIB_EXT_ELE_AAC_UNI_DRC, IISXHEAACENCLIB_DEFAULT_LENGTH_UNIDRC, -1);
           }
diff --git a/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib_delayAndBuffer.c b/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib_delayAndBuffer.c
index 86676a4..c73bf14 100644
--- a/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib_delayAndBuffer.c
+++ b/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib_delayAndBuffer.c
@@ -187,8 +187,7 @@
     int codecDelay = *encoderDelay;
     int drcDelay = 0;
 
-    if (
-        mpegD_drc_on && hConfig->bMpeg4DrcOn) {
+    if ((mpegD_drc_on) && hConfig->bMpeg4DrcOn) {
       retValue = XHEAACENCLIB_RETURN_ERROR_CONFIGURATION;
       printErrorConsole(CDI, "MPEG-D DRC and MPEG-4 DRC are not allowed to be active together");
     }
@@ -199,8 +198,7 @@
       drcDelayData->drcLookAhead = 0;
     }
 
-    if (!isError(retValue) &&
-        mpegD_drc_on) {
+    if (!isError(retValue) && (mpegD_drc_on)) {
       retValueDrc = iisxHEAACEncLib_drc_get_encoder_delay(hDrc, &drcDelayData->drcEncoderDelay);
       if (retValueDrc != DRC_IFC_NO_ERROR) {
         retValue = XHEAACENCLIB_RETURN_ERROR_DELAY_AND_BUFFER;
diff --git a/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib_drc_ifc.c b/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib_drc_ifc.c
index 69d484c..3764821 100644
--- a/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib_drc_ifc.c
+++ b/xhe-aac/iisxHEAACEncLib/src/iisxHEAACEncLib_drc_ifc.c
@@ -334,48 +334,58 @@
 
     uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].drcChannelGroupCount = 1;
 
-    uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications = (GainModifications *)iisCalloc(uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].drcChannelGroupCount, sizeof(GainModifications));
-    if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications == NULL) {
-      return 33;
-    }
-
-    g = 0;
-    {
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainScalingPresent = (int *)iisCalloc(1, sizeof(int));
-      if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainScalingPresent == NULL) {
+    if ((setup->instructionSetup[n].drcSetEffect & IISDRCGAINENC_DRCSETEFFECT_BIT_DUCK_OTHER) || (setup->instructionSetup[n].drcSetEffect & IISDRCGAINENC_DRCSETEFFECT_BIT_DUCK_SELF)) {
+      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pDuckingModifications = (DuckingModifications *)iisCalloc(uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].drcChannelCount, sizeof(DuckingModifications));
+      if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pDuckingModifications == NULL) {
         return 33;
       }
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAttenuationScaling = (float *)iisCalloc(1, sizeof(float));
-      if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAttenuationScaling == NULL) {
-        return 33;
+      for (ch = 0; ch < baseChannelCount; ch++) {
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pDuckingModifications[ch].duckingScalingPresent = 0;
       }
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAmplificationScaling = (float *)iisCalloc(1, sizeof(float));
-      if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAmplificationScaling == NULL) {
-        return 33;
-      }
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffsetPresent = (int *)iisCalloc(1, sizeof(int));
-      if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffsetPresent == NULL) {
-        return 33;
-      }
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffset = (float *)iisCalloc(1, sizeof(float));
-      if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffset == NULL) {
+    } else {
+      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications = (GainModifications *)iisCalloc(uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].drcChannelGroupCount, sizeof(GainModifications));
+      if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications == NULL) {
         return 33;
       }
 
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].shapeFilterPresent = 0;
-      if (setup->instructionSetup[n].attenuationScaling != 1.f || setup->instructionSetup[n].amplificationScaling != 1.f) {
-        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainScalingPresent[0] = 1;
-      } else {
-        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainScalingPresent[0] = 0;
+      g = 0;
+      {
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainScalingPresent = (int *)iisCalloc(1, sizeof(int));
+        if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainScalingPresent == NULL) {
+          return 33;
+        }
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAttenuationScaling = (float *)iisCalloc(1, sizeof(float));
+        if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAttenuationScaling == NULL) {
+          return 33;
+        }
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAmplificationScaling = (float *)iisCalloc(1, sizeof(float));
+        if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAmplificationScaling == NULL) {
+          return 33;
+        }
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffsetPresent = (int *)iisCalloc(1, sizeof(int));
+        if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffsetPresent == NULL) {
+          return 33;
+        }
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffset = (float *)iisCalloc(1, sizeof(float));
+        if (uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffset == NULL) {
+          return 33;
+        }
+
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].shapeFilterPresent = 0;
+        if (setup->instructionSetup[n].attenuationScaling != 1.f || setup->instructionSetup[n].amplificationScaling != 1.f) {
+          uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainScalingPresent[0] = 1;
+        } else {
+          uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainScalingPresent[0] = 0;
+        }
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAttenuationScaling[0] = setup->instructionSetup[n].attenuationScaling;
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAmplificationScaling[0] = setup->instructionSetup[n].amplificationScaling;
+        if (setup->instructionSetup[n].gainOffset != 0.0f) {
+          uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffsetPresent[0] = 1;
+        } else {
+          uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffsetPresent[0] = 0;
+        }
+        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffset[0] = setup->instructionSetup[n].gainOffset;
       }
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAttenuationScaling[0] = setup->instructionSetup[n].attenuationScaling;
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pAmplificationScaling[0] = setup->instructionSetup[n].amplificationScaling;
-      if (setup->instructionSetup[n].gainOffset != 0.0f) {
-        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffsetPresent[0] = 1;
-      } else {
-        uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffsetPresent[0] = 0;
-      }
-      uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].pGainModifications[g].pGainOffset[0] = setup->instructionSetup[n].gainOffset;
     }
     uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].limiterPeakTargetPresent = 0;
     uniDrcConfigExtensionTmp->pDrcInstructionsUniDrcV1[n].limiterPeakTarget = 0.0f;
@@ -599,20 +609,24 @@
       hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcCoefficientsUniDrcV1 = NULL;
 
       for (k = 0; k < hInstance->pUniDrcConfig->uniDrcConfigExtension.drcInstructionsUniDrcV1Count; k++) {
-        for (m = 0; m < hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].drcChannelGroupCount; m++) {
-          iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainOffset);
-          hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainOffset = NULL;
-          iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainOffsetPresent);
-          hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainOffsetPresent = NULL;
-          iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pAmplificationScaling);
-          hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pAmplificationScaling = NULL;
-          iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pAttenuationScaling);
-          hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pAttenuationScaling = NULL;
-          iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainScalingPresent);
-          hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainScalingPresent = NULL;
+        if (hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications) {
+          for (m = 0; m < hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].drcChannelGroupCount; m++) {
+            iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainOffset);
+            hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainOffset = NULL;
+            iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainOffsetPresent);
+            hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainOffsetPresent = NULL;
+            iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pAmplificationScaling);
+            hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pAmplificationScaling = NULL;
+            iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pAttenuationScaling);
+            hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pAttenuationScaling = NULL;
+            iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainScalingPresent);
+            hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications[m].pGainScalingPresent = NULL;
+          }
+          iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications);
+          hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications = NULL;
         }
-        iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications);
-        hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainModifications = NULL;
+        iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pDuckingModifications);
+        hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pDuckingModifications = NULL;
         iisFree(hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainSetIndex);
         hInstance->pUniDrcConfig->uniDrcConfigExtension.pDrcInstructionsUniDrcV1[k].pGainSetIndex = NULL;
       }
diff --git a/xhe-aac/mp4bitmux/src/aac/bit_aac.c b/xhe-aac/mp4bitmux/src/aac/bit_aac.c
index 1fb0a46..2a33372 100644
--- a/xhe-aac/mp4bitmux/src/aac/bit_aac.c
+++ b/xhe-aac/mp4bitmux/src/aac/bit_aac.c
@@ -112,6 +112,7 @@
 static const int globalGainOffset = 100;
 static const int noiseOffset = 90;
 static const int icsReservedBit = 0;
+#define MAX_PREDICTION_COEF 30
 
 int encodeGlobalGain(BS_SCALEFAC_DATA *scalefacData,
                      int firstSCF,
@@ -239,176 +240,154 @@
   return (bitCount);
 }
 
-int countBitsScf(int delta) {
-  return huff_ltabscf[delta + CODE_BOOK_SCF_LAV];
+static int limitToScfLAV(int scf) {
+  if (scf > CODE_BOOK_SCF_LAV) {
+    scf = CODE_BOOK_SCF_LAV;
+  }
+  if (scf < -CODE_BOOK_SCF_LAV) {
+    scf = -CODE_BOOK_SCF_LAV;
+  }
+  return scf;
 }
 
-int encodeCplxPredData(int sfbCnt,
-                       int grpSfb,
-                       int maxSfb,
+int encodeCplxPredData(const int sfbCnt,
+                       const int grpSfb,
+                       const int maxSfb,
                        const int *jsFlag,
-                       const int *predCoeffRe, const int *predCoeffIm,
-                       int *predCoeffPrevRe, int *predCoeffPrevIm,
-                       int *bPredCoeffRealOnly,
-                       int bResetPredictors, int nGroupsPrev,
-                       int wSeq, int wSeqPrev,
-                       int sfbPerPredBand,
-                       int bSwap,
-                       int bUsePrevFrame,
+                       const int *predCoefRe, const int *predCoefIm,
+                       int *predCoefPrevRe, int *predCoefPrevIm,
+                       const int bResetPredictors, const int nGroupsPrev,
+                       const BLOCK_TYPE windowSequence, const BLOCK_TYPE windowSequencePrev,
+                       const int sfbPerPredBand,
+                       const int bUsePrevFrame,
                        HANDLE_BIT_BUF hBitStream,
-                       int const bUsacIndependenceFlag) {
-  int bComplex = 0;
-  int sfbOff = 0;
-  int i = 0;
-  int bitCount = 0;
-  int bDeltaTime = 0;
-  int nBits[2] = {INT_MAX, INT_MAX};
+                       const int bUsacIndependenceFlag) {
+  int bDeltaTimeCoding = 0;
+  int nBitsDeltaFreq = INT_MAX;
+  int nBitsDeltaTime = INT_MAX;
   int deltaRe[2][MAX_GROUPED_SFB] = {{0}};
   int deltaIm[2][MAX_GROUPED_SFB] = {{0}};
-  int huffRe_bits = 0;
-  int huffIm_bits = 0;
+  int bComplex = 0;
+  int sfbOffset = 0;
+  int sfb = 0;
+  int bitCount = 0;
 
   assert(sfbPerPredBand == 2);
 
-  if (((wSeq == SHORT_WINDOW) && (wSeqPrev != SHORT_WINDOW)) ||
-      ((wSeqPrev == SHORT_WINDOW) && (wSeq != SHORT_WINDOW))) {
-    memset(predCoeffPrevRe, 0, MAX_GROUPED_SFB * sizeof(int));
-    memset(predCoeffPrevIm, 0, MAX_GROUPED_SFB * sizeof(int));
+  if (((windowSequence == SHORT_WINDOW) && (windowSequencePrev != SHORT_WINDOW)) ||
+      ((windowSequencePrev == SHORT_WINDOW) && (windowSequence != SHORT_WINDOW))) {
+    setINT(0, predCoefPrevRe, MAX_GROUPED_SFB);
+    setINT(0, predCoefPrevIm, MAX_GROUPED_SFB);
     assert(bResetPredictors == 1);
   }
 
-  for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
-    for (i = 0; i < maxSfb; i += sfbPerPredBand) {
-      if (predCoeffIm[sfbOff + i] != 0) {
+  for (sfbOffset = 0; sfbOffset < sfbCnt; sfbOffset += grpSfb) {
+    for (sfb = 0; sfb < maxSfb; sfb += sfbPerPredBand) {
+      if ((abs(predCoefRe[sfbOffset + sfb]) > MAX_PREDICTION_COEF) | (abs(predCoefIm[sfbOffset + sfb]) > MAX_PREDICTION_COEF)) {
+        assert(0);
+        freeErrorTraceback(iisUtil_ERROR(CDI, "Complex prediction encoding out of bound"));
+
+        if (hBitStream == NULL) {
+          return MAX_GROUPED_SFB * huff_ltabscf[2 * CODE_BOOK_SCF_LAV];
+        }
+      }
+
+      if (predCoefIm[sfbOffset + sfb] != 0) {
         bComplex = 1;
       }
     }
   }
 
-  if (bPredCoeffRealOnly != 0) {
-    *bPredCoeffRealOnly = !bComplex;
-  }
-
-  bitCount += WriteBits(hBitStream, bSwap, 1);
-
+  bitCount += WriteBits(hBitStream, bComplex, 1);
   if (bComplex) {
-    bitCount += WriteBits(hBitStream, 1, 1);
     if (bUsacIndependenceFlag == 0) {
       bitCount += WriteBits(hBitStream, bUsePrevFrame, 1);
     }
-  } else {
-    bitCount += WriteBits(hBitStream, 0, 1);
   }
 
-  for (bDeltaTime = 0; bDeltaTime < 2 - bResetPredictors; bDeltaTime++) {
-    nBits[bDeltaTime] = 0;
-    for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
-      for (i = 0; i < maxSfb; i += sfbPerPredBand) {
-        if (jsFlag[sfbOff + i]) {
+  for (int codingMethod = 0; codingMethod < (bResetPredictors ? 1 : 2); codingMethod++) {
+    if (codingMethod) {
+      nBitsDeltaTime = 0;
+    } else {
+      nBitsDeltaFreq = 0;
+    }
+
+    for (sfbOffset = 0; sfbOffset < sfbCnt; sfbOffset += grpSfb) {
+      for (sfb = 0; sfb < maxSfb; sfb += sfbPerPredBand) {
+        if (jsFlag[sfbOffset + sfb]) {
           int predRe;
           int predIm;
 
-          if (i != (maxSfb - 1)) {
-            assert(jsFlag[sfbOff + i + (sfbPerPredBand - 1)] == 1);
-          }
-          if (bDeltaTime) {
-            if (sfbOff > 0) {
-              predRe = predCoeffRe[sfbOff - grpSfb + i];
-              predIm = predCoeffIm[sfbOff - grpSfb + i];
-            } else if (wSeq == SHORT_WINDOW && wSeq == wSeqPrev) {
-              assert(sfbOff == 0);
+          assert((sfb == (maxSfb - 1)) || (jsFlag[sfbOffset + sfb + (sfbPerPredBand - 1)] == 1));
 
-              predRe = predCoeffPrevRe[(nGroupsPrev - 1) * grpSfb + i];
-              predIm = predCoeffPrevIm[(nGroupsPrev - 1) * grpSfb + i];
+          if (codingMethod) {
+            if (sfbOffset > 0) {
+              predRe = predCoefRe[sfbOffset + sfb - grpSfb];
+              predIm = predCoefIm[sfbOffset + sfb - grpSfb];
+
+            } else if (windowSequence == SHORT_WINDOW && windowSequence == windowSequencePrev) {
+              assert(sfbOffset == 0);
+
+              predRe = predCoefPrevRe[(nGroupsPrev - 1) * grpSfb + sfb];
+              predIm = predCoefPrevIm[(nGroupsPrev - 1) * grpSfb + sfb];
+
             } else {
-              predRe = predCoeffPrevRe[sfbOff + i];
-              predIm = predCoeffPrevIm[sfbOff + i];
+              predRe = predCoefPrevRe[sfbOffset + sfb];
+              predIm = predCoefPrevIm[sfbOffset + sfb];
+            }
+
+          } else {
+            if (sfb % grpSfb != 0) {
+              predRe = predCoefRe[sfbOffset + sfb - sfbPerPredBand];
+              predIm = predCoefIm[sfbOffset + sfb - sfbPerPredBand];
+            } else {
+              predRe = 0;
+              predIm = 0;
+            }
+          }
+
+          deltaRe[codingMethod][sfbOffset + sfb] = limitToScfLAV(predCoefRe[sfbOffset + sfb] - predRe);
+          deltaIm[codingMethod][sfbOffset + sfb] = limitToScfLAV(predCoefIm[sfbOffset + sfb] - predIm);
+          const int nHuffReBits = huff_ltabscf[deltaRe[codingMethod][sfbOffset + sfb] + CODE_BOOK_SCF_LAV];
+          const int nHuffImBits = huff_ltabscf[deltaIm[codingMethod][sfbOffset + sfb] + CODE_BOOK_SCF_LAV];
+
+          if (codingMethod) {
+            nBitsDeltaTime += nHuffReBits;
+            if (bComplex) {
+              nBitsDeltaTime += nHuffImBits;
             }
           } else {
-            if (i % grpSfb != 0) {
-              predRe = predCoeffRe[sfbOff + i - sfbPerPredBand];
-              predIm = predCoeffIm[sfbOff + i - sfbPerPredBand];
-            } else {
-              predRe = predIm = 0;
-            }
-          }
-
-          deltaRe[bDeltaTime][sfbOff + i] = predCoeffRe[sfbOff + i] - predRe;
-          deltaIm[bDeltaTime][sfbOff + i] = predCoeffIm[sfbOff + i] - predIm;
-
-          huffRe_bits = huff_ltabscf[deltaRe[bDeltaTime][sfbOff + i] + CODE_BOOK_SCF_LAV];
-          huffIm_bits = huff_ltabscf[deltaIm[bDeltaTime][sfbOff + i] + CODE_BOOK_SCF_LAV];
-
-          if (deltaRe[bDeltaTime][sfbOff + i] < -CODE_BOOK_SCF_LAV ||
-              deltaRe[bDeltaTime][sfbOff + i] > CODE_BOOK_SCF_LAV) {
-            nBits[bDeltaTime] = INT_MAX;
-
-            assert(0);
-          }
-
-          if (huffRe_bits > 0 && (nBits[bDeltaTime] <= INT_MAX - huffRe_bits)) {
-            nBits[bDeltaTime] += WriteBits(0, huff_ctabscf[deltaRe[bDeltaTime][sfbOff + i] + CODE_BOOK_SCF_LAV], huffRe_bits);
-          }
-
-          if (bComplex) {
-            if (deltaIm[bDeltaTime][sfbOff + i] < -CODE_BOOK_SCF_LAV ||
-                deltaIm[bDeltaTime][sfbOff + i] > CODE_BOOK_SCF_LAV) {
-              nBits[bDeltaTime] = INT_MAX;
-
-              assert(0);
-            }
-
-            if (huffIm_bits > 0 && (nBits[bDeltaTime] <= INT_MAX - huffIm_bits)) {
-              nBits[bDeltaTime] += WriteBits(0, huff_ctabscf[deltaIm[bDeltaTime][sfbOff + i] + CODE_BOOK_SCF_LAV], huffIm_bits);
+            nBitsDeltaFreq += nHuffReBits;
+            if (bComplex) {
+              nBitsDeltaFreq += nHuffImBits;
             }
           }
         }
       }
     }
   }
+
   if (bUsacIndependenceFlag) {
-    bDeltaTime = 0;
+    bDeltaTimeCoding = 0;
   } else {
-    if (nBits[0] < nBits[1]) {
-      bDeltaTime = 0;
-      bitCount += WriteBits(hBitStream, 0, 1);
+    if (nBitsDeltaFreq < nBitsDeltaTime) {
+      bDeltaTimeCoding = 0;
     } else {
-      bDeltaTime = 1;
-      bitCount += WriteBits(hBitStream, 1, 1);
+      bDeltaTimeCoding = 1;
     }
+    bitCount += WriteBits(hBitStream, bDeltaTimeCoding, 1);
   }
 
-  for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
-    for (i = 0; i < maxSfb; i += sfbPerPredBand) {
-      if (jsFlag[sfbOff + i]) {
-        if (deltaRe[bDeltaTime][sfbOff + i] < -CODE_BOOK_SCF_LAV ||
-            deltaRe[bDeltaTime][sfbOff + i] > CODE_BOOK_SCF_LAV) {
-          assert(0);
+  for (sfbOffset = 0; sfbOffset < sfbCnt; sfbOffset += grpSfb) {
+    for (sfb = 0; sfb < maxSfb; sfb += sfbPerPredBand) {
+      if (jsFlag[sfbOffset + sfb]) {
+        const int nHuffReBits = huff_ltabscf[deltaRe[bDeltaTimeCoding][sfbOffset + sfb] + CODE_BOOK_SCF_LAV];
+        const int nHuffImBits = huff_ltabscf[deltaIm[bDeltaTimeCoding][sfbOffset + sfb] + CODE_BOOK_SCF_LAV];
 
-          if (deltaRe[bDeltaTime][sfbOff + i] < -CODE_BOOK_SCF_LAV) {
-            deltaRe[bDeltaTime][sfbOff + i] = -CODE_BOOK_SCF_LAV;
-          } else if (deltaRe[bDeltaTime][sfbOff + i] > CODE_BOOK_SCF_LAV) {
-            deltaRe[bDeltaTime][sfbOff + i] = CODE_BOOK_SCF_LAV;
-          }
-        }
-
-        bitCount += WriteBits(hBitStream, huff_ctabscf[deltaRe[bDeltaTime][sfbOff + i] + CODE_BOOK_SCF_LAV],
-                              huff_ltabscf[deltaRe[bDeltaTime][sfbOff + i] + CODE_BOOK_SCF_LAV]);
+        bitCount += WriteBits(hBitStream, huff_ctabscf[deltaRe[bDeltaTimeCoding][sfbOffset + sfb] + CODE_BOOK_SCF_LAV], nHuffReBits);
 
         if (bComplex) {
-          if (deltaIm[bDeltaTime][sfbOff + i] < -CODE_BOOK_SCF_LAV ||
-              deltaIm[bDeltaTime][sfbOff + i] > CODE_BOOK_SCF_LAV) {
-            assert(0);
-
-            if (deltaIm[bDeltaTime][sfbOff + i] < -CODE_BOOK_SCF_LAV) {
-              deltaIm[bDeltaTime][sfbOff + i] = -CODE_BOOK_SCF_LAV;
-            } else if (deltaIm[bDeltaTime][sfbOff + i] > CODE_BOOK_SCF_LAV) {
-              deltaIm[bDeltaTime][sfbOff + i] = CODE_BOOK_SCF_LAV;
-            }
-          }
-
-          bitCount += WriteBits(hBitStream, huff_ctabscf[deltaIm[bDeltaTime][sfbOff + i] + CODE_BOOK_SCF_LAV],
-                                huff_ltabscf[deltaIm[bDeltaTime][sfbOff + i] + CODE_BOOK_SCF_LAV]);
+          bitCount += WriteBits(hBitStream, huff_ctabscf[deltaIm[bDeltaTimeCoding][sfbOffset + sfb] + CODE_BOOK_SCF_LAV], nHuffImBits);
         }
       }
     }
@@ -478,12 +457,12 @@
   if (msAllOn) {
     if (bCplxPredActive) {
       bitCount += WriteBits(hBitStream, 1, 1);
+      bitCount += WriteBits(hBitStream, bSwap, 1);
       bitCount += encodeCplxPredData(sfbCnt, grpSfb, maxSfb, jsFlag,
                                      predCoeffRe, predCoeffIm, predCoeffPrevRe, predCoeffPrevIm,
-                                     0, bResetPredictors, nGroupsPrev,
+                                     bResetPredictors, nGroupsPrev,
                                      wSeq, wSeqPrev,
                                      sfbPerPredBand,
-                                     bSwap,
                                      bUsePrevFrame,
                                      hBitStream,
                                      bUsacIndependenceFlag);
@@ -534,12 +513,12 @@
         }
       }
     }
+    bitCount += WriteBits(hBitStream, bSwap, 1);
     bitCount += encodeCplxPredData(sfbCnt, grpSfb, maxSfb, jsFlag,
                                    predCoeffRe, predCoeffIm, predCoeffPrevRe, predCoeffPrevIm,
-                                   0, bResetPredictors, nGroupsPrev,
+                                   bResetPredictors, nGroupsPrev,
                                    wSeq, wSeqPrev,
                                    sfbPerPredBand,
-                                   bSwap,
                                    bUsePrevFrame,
                                    hBitStream,
                                    bUsacIndependenceFlag);
diff --git a/xhe-aac/mp4bitmux/src/aac/bit_aac.h b/xhe-aac/mp4bitmux/src/aac/bit_aac.h
index 4decf22..897ccb0 100644
--- a/xhe-aac/mp4bitmux/src/aac/bit_aac.h
+++ b/xhe-aac/mp4bitmux/src/aac/bit_aac.h
@@ -100,6 +100,7 @@
 
 #include "glob_con.h"
 #include "bit_buf.h"
+#include "mathlib.h"
 #include "iisArithEncoder.h"
 
 enum _si_bis {
@@ -363,11 +364,9 @@
                        const int *jsFlag,
                        const int *predCoeffRe, const int *predCoeffIm,
                        int *predCoeffPrevRe, int *predCoeffPrevIm,
-                       int *bPredCoeffRealOnly,
                        int bResetPredictors, int nGroupsPrev,
-                       int wSeq, int wSeqPrev,
+                       BLOCK_TYPE windowSequence, BLOCK_TYPE windowSequencePrev,
                        int sfbPerPredBand,
-                       int bSwap,
                        int bUsePrevFrame,
                        HANDLE_BIT_BUF hBitStream,
                        int const bUsacIndependenceFlag);
diff --git a/xhe-aac/sbrEnclib/src/fram_gen.c b/xhe-aac/sbrEnclib/src/fram_gen.c
index ebdb677..c04ac5a 100644
--- a/xhe-aac/sbrEnclib/src/fram_gen.c
+++ b/xhe-aac/sbrEnclib/src/fram_gen.c
@@ -1396,7 +1396,7 @@
     switch (frameClass) {
       case VARFIX:
 
-        calcFillLengthMaxSibi(CODEC_SAAC,
+        calcFillLengthMaxSibi(coreCodec,
                               numberTimeSlots,
                               &fmax);
 
diff --git a/xhe-aac/spaceEnclib/include/spaceEnclib.h b/xhe-aac/spaceEnclib/include/spaceEnclib.h
index 4871168..c76f39e 100644
--- a/xhe-aac/spaceEnclib/include/spaceEnclib.h
+++ b/xhe-aac/spaceEnclib/include/spaceEnclib.h
@@ -244,7 +244,7 @@
   MP4SPACEENC_IPDMODE_INVALID = -1,
   MP4SPACEENC_IPDMODE_NONE = 0,
   MP4SPACEENC_IPDMODE_NO_RESIDUAL = 1,
-  MP4SPACEENC_IPDMODE_RESIDUAL = 3
+  MP4SPACEENC_IPDMODE_RESIDUAL = 2
 } MP4SPACEENC_IPDMODE;
 
 typedef enum {
diff --git a/xhe-aac/spaceEnclib/src/spaceEnclib.c b/xhe-aac/spaceEnclib/src/spaceEnclib.c
index 280a740..536d367 100644
--- a/xhe-aac/spaceEnclib/src/spaceEnclib.c
+++ b/xhe-aac/spaceEnclib/src/spaceEnclib.c
@@ -97,6 +97,7 @@
 
 #include <string.h>
 #include <math.h>
+#include <stddef.h>
 
 #include "spaceEnclib_const.h"
 
@@ -276,7 +277,6 @@
   int bPseudoLr;
   int bPsStyleDmx;
   int speechFlag;
-  float korSpeechGainLast;
 };
 
 static unsigned int const pValidBands[8] = {4, 5, 7, 10, 14, 20, 28, 40};
@@ -291,6 +291,27 @@
 static HANDLE_ERROR_INFO
 mp4SpaceEnc_Reset(HANDLE_MP4SPACE_ENCODER const hEnc);
 
+static void mp4SpaceEnc_rotateDmxResToPseudoLR(float *hRe,
+                                               float *hIm);
+
+static void mp4SpaceEnc_MoveBufUmxParamToFront(int ts,
+                                               int delayUmxMat2Mdct,
+                                               int numParamBands,
+                                               float cld[][28],
+                                               float umxMatRe[][28][4],
+                                               float umxMatIm[][28][4],
+                                               int nTimeSlots);
+
+static void mp4SpaceEnc_AddBufUmxParamToEnd(HANDLE_MP4SPACE_ENCODER const hMp4SpaceEnc,
+                                            int ts,
+                                            int delayUmxMat2Mdct,
+                                            float cld[][28],
+                                            float umxMatRe[][28][4],
+                                            float umxMatIm[][28][4],
+                                            int nTimeSlots,
+                                            int const subband2parameterBand[],
+                                            int bPseudoLr);
+
 static HANDLE_ERROR_INFO
 mapTempShapeConfig(TEMPSHAPECONFIG *const outTempShapeConfig,
                    MP4SPACEENC_TEMPSHAPECONFIG const inTempShapeConfig);
@@ -345,7 +366,6 @@
     hEnc->bPseudoLr = 0;
     hEnc->bPsStyleDmx = 0;
     hEnc->speechFlag = 0;
-    hEnc->korSpeechGainLast = 1.f;
 
     hEnc->nPredictionBands = 0;
 
@@ -1166,8 +1186,6 @@
   float ***pppTreeOutputReal = NULL;
   float ***pppTreeOutputImag = NULL;
 
-  int bKorSpeech = 0;
-
   if (error == noError) {
     if (NULL == hMp4SpaceEnc) {
       error = iisUtil_ERROR(CDI, "Invalid Handle");
@@ -1498,27 +1516,6 @@
     }
   }
 
-  if (hMp4SpaceEnc->residualConfig.mode > 0 && hMp4SpaceEnc->encMode == MP4SPACEENC_USAC_212) {
-    float **ppHybOutResReal = hMp4SpaceEnc->pppHybridOutReal[1];
-    float **ppHybOutResImag = hMp4SpaceEnc->pppHybridOutImag[1];
-    unsigned int hb;
-    float resGain;
-    float resGainOld;
-    float resGainNew = 1.0f;
-
-    resGainOld = hMp4SpaceEnc->korSpeechGainLast;
-    resGainNew = (bKorSpeech) ? 0.0f : 1.0f;
-    hMp4SpaceEnc->korSpeechGainLast = resGainNew;
-
-    for (ts = 0; ts < nFrameTimeSlots; ts++) {
-      resGain = resGainOld + (resGainNew - resGainOld) * (float)(ts + 1) / (nFrameTimeSlots);
-      for (hb = 0; hb < hMp4SpaceEnc->nHybridBands; hb++) {
-        ppHybOutResReal[ts][hb] *= resGain;
-        ppHybOutResImag[ts][hb] *= resGain;
-      }
-    }
-  }
-
   if ((error == noError) && (hMp4SpaceEnc->tempShapeConfig == MP4SPACEENC_TEMPSHAPE_TSD)) {
     SAFECALL(error, CalcTSDphase(&pFrameData->tsdData,
                                  hMp4SpaceEnc->pppHybridOutReal,
@@ -1884,6 +1881,82 @@
   return error;
 }
 
+static void mp4SpaceEnc_rotateDmxResToPseudoLR(float *hRe,
+                                               float *hIm) {
+  float const cos_pi_4 = 1.0f / (float)sqrt(2.0f);
+
+  for (int r = 0; r < 2; ++r) {
+    const float hr0 = hRe[2 * r + 0], hr1 = hRe[2 * r + 1];
+    const float hi0 = hIm[2 * r + 0], hi1 = hIm[2 * r + 1];
+
+    hRe[2 * r + 0] = (hr0 + hr1) * cos_pi_4;
+    hRe[2 * r + 1] = (hr0 - hr1) * cos_pi_4;
+
+    hIm[2 * r + 0] = (hi0 + hi1) * cos_pi_4;
+    hIm[2 * r + 1] = (hi0 - hi1) * cos_pi_4;
+  }
+}
+
+static void mp4SpaceEnc_MoveBufUmxParamToFront(int ts,
+                                               int delayUmxMat2Mdct,
+                                               int numParamBands,
+                                               float cld[][28],
+                                               float umxMatRe[][28][4],
+                                               float umxMatIm[][28][4],
+                                               int nTimeSlots) {
+  int paramBand = 0, inCh = 0, outCh = 0;
+  for (ts = 0; ts < delayUmxMat2Mdct; ts++) {
+    for (paramBand = 0; paramBand < numParamBands; paramBand++) {
+      for (inCh = 0; inCh < 2; inCh++) {
+        for (outCh = 0; outCh < 2; outCh++) {
+          umxMatRe[ts][paramBand][2 * outCh + inCh] = umxMatRe[nTimeSlots + ts][paramBand][2 * outCh + inCh];
+          umxMatIm[ts][paramBand][2 * outCh + inCh] = umxMatIm[nTimeSlots + ts][paramBand][2 * outCh + inCh];
+        }
+      }
+      cld[ts][paramBand] = cld[nTimeSlots + ts][paramBand];
+    }
+  }
+}
+
+static void mp4SpaceEnc_AddBufUmxParamToEnd(HANDLE_MP4SPACE_ENCODER const hMp4SpaceEnc,
+                                            int ts,
+                                            int delayUmxMat2Mdct,
+                                            float cld[][28],
+                                            float umxMatRe[][28][4],
+                                            float umxMatIm[][28][4],
+                                            int nTimeSlots,
+                                            int const subband2parameterBand[],
+                                            int bPseudoLr) {
+  int paramBand = 0, inCh = 0, outCh = 0, hybBand = 0;
+
+  for (ts = 0; ts < nTimeSlots; ts++) {
+    for (hybBand = 0; hybBand < (int)hMp4SpaceEnc->nHybridBands; hybBand++) {
+      paramBand = subband2parameterBand[hybBand];
+      assert(paramBand < (int)hMp4SpaceEnc->nParamBands);
+      for (inCh = 0; inCh < 2; inCh++) {
+        for (outCh = 0; outCh < 2; outCh++) {
+          umxMatRe[delayUmxMat2Mdct + ts][paramBand][2 * outCh + inCh] = hMp4SpaceEnc->ppUmxMatReal[outCh][inCh][ts][hybBand];
+          umxMatIm[delayUmxMat2Mdct + ts][paramBand][2 * outCh + inCh] = hMp4SpaceEnc->ppUmxMatImag[outCh][inCh][ts][hybBand];
+
+          staticGain_ApplyInverseDmxGain(hMp4SpaceEnc->hStaticGain, &(umxMatRe[delayUmxMat2Mdct + ts][paramBand][2 * outCh + inCh]), 1);
+          staticGain_ApplyInverseDmxGain(hMp4SpaceEnc->hStaticGain, &(umxMatIm[delayUmxMat2Mdct + ts][paramBand][2 * outCh + inCh]), 1);
+        }
+      }
+
+      if (paramBand >= (int)(hMp4SpaceEnc->residualConfig.bands[0] + 1)) {
+        umxMatRe[delayUmxMat2Mdct + ts][paramBand][1] = umxMatIm[delayUmxMat2Mdct + ts][paramBand][1] = 0.0f;
+        umxMatRe[delayUmxMat2Mdct + ts][paramBand][3] = umxMatIm[delayUmxMat2Mdct + ts][paramBand][3] = 0.0f;
+      }
+
+      if (bPseudoLr && hMp4SpaceEnc->nOutputChannels == 2) {
+        mp4SpaceEnc_rotateDmxResToPseudoLR(umxMatRe[delayUmxMat2Mdct + ts][paramBand], umxMatIm[delayUmxMat2Mdct + ts][paramBand]);
+      }
+
+      cld[delayUmxMat2Mdct + ts][paramBand] = SpaceTree_GetUniSteCld(hMp4SpaceEnc->hSpaceTree, paramBand);
+    }
+  }
+}
+
 HANDLE_ERROR_INFO
 mp4SpaceEnc_UniSteUpdateFrame(HANDLE_MP4SPACE_ENCODER const hMp4SpaceEnc,
                               float umxMatRe[][28][4],
@@ -1891,11 +1964,9 @@
                               float cld[][28],
                               int delayUmxMat2Mdct,
                               int bPseudoLr) {
-  int i;
   HANDLE_ERROR_INFO error = noError;
 
-  int ts, paramBand, i_ch, o_ch;
-  unsigned int hybBand = 0;
+  int ts = 0;
   MPS_MODE mode = MPS_MODE_USAC;
   const int *subband2parameterBand = NULL;
   BOX_SUBBAND_CONFIG nParamBands;
@@ -1910,66 +1981,9 @@
   if (error == noError) {
     subband2parameterBand = getSubband2ParameterIndex(nParamBands, mode);
 
-    for (ts = 0; ts < delayUmxMat2Mdct; ts++) {
-      for (paramBand = 0; paramBand < (int)hMp4SpaceEnc->nParamBands; paramBand++) {
-        for (i_ch = 0; i_ch < 2; i_ch++) {
-          for (o_ch = 0; o_ch < 2; o_ch++) {
-            umxMatRe[ts][paramBand][2 * o_ch + i_ch] = umxMatRe[nTimeSlots + ts][paramBand][2 * o_ch + i_ch];
-            umxMatIm[ts][paramBand][2 * o_ch + i_ch] = umxMatIm[nTimeSlots + ts][paramBand][2 * o_ch + i_ch];
-          }
-        }
-        cld[ts][paramBand] = cld[nTimeSlots + ts][paramBand];
-      }
-    }
+    mp4SpaceEnc_MoveBufUmxParamToFront(ts, delayUmxMat2Mdct, (int)hMp4SpaceEnc->nParamBands, cld, umxMatRe, umxMatIm, nTimeSlots);
 
-    for (ts = 0; ts < nTimeSlots; ts++) {
-      for (hybBand = 0; hybBand < hMp4SpaceEnc->nHybridBands; hybBand++) {
-        paramBand = subband2parameterBand[hybBand];
-        assert(paramBand < (int)hMp4SpaceEnc->nParamBands);
-        for (i_ch = 0; i_ch < 2; i_ch++) {
-          for (o_ch = 0; o_ch < 2; o_ch++) {
-            umxMatRe[delayUmxMat2Mdct + ts][paramBand][2 * o_ch + i_ch] = hMp4SpaceEnc->ppUmxMatReal[o_ch][i_ch][ts][hybBand];
-            umxMatIm[delayUmxMat2Mdct + ts][paramBand][2 * o_ch + i_ch] = hMp4SpaceEnc->ppUmxMatImag[o_ch][i_ch][ts][hybBand];
-
-            staticGain_ApplyInverseDmxGain(hMp4SpaceEnc->hStaticGain, &(umxMatRe[delayUmxMat2Mdct + ts][paramBand][2 * o_ch + i_ch]), 1);
-            staticGain_ApplyInverseDmxGain(hMp4SpaceEnc->hStaticGain, &(umxMatIm[delayUmxMat2Mdct + ts][paramBand][2 * o_ch + i_ch]), 1);
-          }
-        }
-
-        if (paramBand >= (int)(hMp4SpaceEnc->residualConfig.bands[0] + 1)) {
-          umxMatRe[delayUmxMat2Mdct + ts][paramBand][1] = umxMatIm[delayUmxMat2Mdct + ts][paramBand][1] = 0.0f;
-          umxMatRe[delayUmxMat2Mdct + ts][paramBand][3] = umxMatIm[delayUmxMat2Mdct + ts][paramBand][3] = 0.0f;
-        }
-
-        if (bPseudoLr && hMp4SpaceEnc->nOutputChannels == 2) {
-          float tmpRe[4];
-          float tmpIm[4];
-
-          const float *hRe = umxMatRe[delayUmxMat2Mdct + ts][paramBand];
-          const float *hIm = umxMatIm[delayUmxMat2Mdct + ts][paramBand];
-          float p[4];
-          p[0] = p[1] = p[2] = 1.0f / (float)sqrt(2.0f);
-          p[3] = -1.0f / (float)sqrt(2.0f);
-
-          tmpRe[0] = hRe[0] * p[0] + hRe[1] * p[2];
-          tmpRe[1] = hRe[0] * p[1] + hRe[1] * p[3];
-          tmpRe[2] = hRe[2] * p[0] + hRe[3] * p[2];
-          tmpRe[3] = hRe[2] * p[1] + hRe[3] * p[3];
-
-          tmpIm[0] = hIm[0] * p[0] + hIm[1] * p[2];
-          tmpIm[1] = hIm[0] * p[1] + hIm[1] * p[3];
-          tmpIm[2] = hIm[2] * p[0] + hIm[3] * p[2];
-          tmpIm[3] = hIm[2] * p[1] + hIm[3] * p[3];
-
-          for (i = 0; i < 4; i++) {
-            umxMatRe[delayUmxMat2Mdct + ts][paramBand][i] = tmpRe[i];
-            umxMatIm[delayUmxMat2Mdct + ts][paramBand][i] = tmpIm[i];
-          }
-        }
-
-        cld[delayUmxMat2Mdct + ts][paramBand] = SpaceTree_GetUniSteCld(hMp4SpaceEnc->hSpaceTree, paramBand);
-      }
-    }
+    mp4SpaceEnc_AddBufUmxParamToEnd(hMp4SpaceEnc, ts, delayUmxMat2Mdct, cld, umxMatRe, umxMatIm, nTimeSlots, subband2parameterBand, bPseudoLr);
   }
   return error;
 }
diff --git a/xhe-aac/spaceEnclib/src/space_bitstream.c b/xhe-aac/spaceEnclib/src/space_bitstream.c
index e6ffffa..31e927b 100644
--- a/xhe-aac/spaceEnclib/src/space_bitstream.c
+++ b/xhe-aac/spaceEnclib/src/space_bitstream.c
@@ -567,18 +567,15 @@
         }
       }
 
-      if (error == noError && spatialSpecificConfig->bsTreeConfig == TREE_USAC_212) {
-        if ((spatialSpecificConfig->bsIpdMode >> 2) > 0) {
-          error = iisUtil_ERROR(CDI, "Invalid IPD mode.");
+      if (error == noError) {
+        if (spatialSpecificConfig->bsIpdMode > IPDMODE_INVALID && spatialSpecificConfig->bsIpdMode <= IPDMODE_LAST) {
+          nBitsWritten += WriteBits(bitstream, spatialSpecificConfig->bsIpdMode > IPDMODE_NONE, 1);
         } else {
-          if (spatialSpecificConfig->bsIpdMode == 2) {
-            error = iisUtil_ERROR(CDI, "ERROR: m16921 syntax incompatible with IPD mode 2.\n");
-          }
-          nBitsWritten += WriteBits(bitstream, spatialSpecificConfig->bsIpdMode > 0, 1);
+          error = iisUtil_ERROR(CDI, "Invalid bsIpdMode.");
         }
       }
 
-      if (error == noError && spatialSpecificConfig->bsTreeConfig == TREE_USAC_212) {
+      if (error == noError) {
         if ((spatialSpecificConfig->bsOttBandsPhasePresent >> 1) > 0) {
           error = iisUtil_ERROR(CDI, "Invalid bsOttBandsPhasePresent.");
         } else {
@@ -586,7 +583,7 @@
         }
       }
 
-      if (spatialSpecificConfig->bsOttBandsPhasePresent && spatialSpecificConfig->bsTreeConfig == TREE_USAC_212) {
+      if (spatialSpecificConfig->bsOttBandsPhasePresent) {
         if (error == noError) {
           if ((spatialSpecificConfig->bsOttBandsPhase >> 5) > 0) {
             error = iisUtil_ERROR(CDI, "Invalid bsOttBandsPhase.");
@@ -597,14 +594,16 @@
       }
 
       if (spatialSpecificConfig->bsResidualCoding) {
-        if ((spatialSpecificConfig->residualConfig[0].bsResidualBands >> 5) > 0) {
-          error = iisUtil_ERROR(CDI, "Invalid downmix type.");
-        } else {
-          nBitsWritten += WriteBits(bitstream, spatialSpecificConfig->residualConfig[0].bsResidualBands, 5);
-        }
-
         if (error == noError) {
-          nBitsWritten += WriteBits(bitstream, spatialSpecificConfig->bsPseudoLr, 1);
+          if ((spatialSpecificConfig->residualConfig[0].bsResidualBands >> 5) > 0) {
+            error = iisUtil_ERROR(CDI, "Invalid bsResidualBands.");
+          } else {
+            nBitsWritten += WriteBits(bitstream, spatialSpecificConfig->residualConfig[0].bsResidualBands, 5);
+          }
+
+          if (error == noError) {
+            nBitsWritten += WriteBits(bitstream, spatialSpecificConfig->bsPseudoLr, 1);
+          }
         }
       }
     }
diff --git a/xhe-aac/spaceEnclib/src/space_bitstream.h b/xhe-aac/spaceEnclib/src/space_bitstream.h
index 4bd6015..89b6e33 100644
--- a/xhe-aac/spaceEnclib/src/space_bitstream.h
+++ b/xhe-aac/spaceEnclib/src/space_bitstream.h
@@ -184,7 +184,8 @@
   IPDMODE_INVALID = -1,
   IPDMODE_NONE = 0,
   IPDMODE_NO_RESIDUAL = 1,
-  IPDMODE_RESIDUAL = 3
+  IPDMODE_RESIDUAL = 2,
+  IPDMODE_LAST = IPDMODE_RESIDUAL
 } IPDMODE;
 
 typedef enum {
diff --git a/xhe-aac/spaceEnclib/src/space_paramextract.c b/xhe-aac/spaceEnclib/src/space_paramextract.c
index 52c7053..be35a8b 100644
--- a/xhe-aac/spaceEnclib/src/space_paramextract.c
+++ b/xhe-aac/spaceEnclib/src/space_paramextract.c
@@ -106,9 +106,27 @@
 #include "space_paramextract.h"
 #include "space_tree.h"
 
+#if defined __GNUC__ || defined __clang__
+#define ABSTEREOSPEECH __attribute__((unused))
+#else
+#define ABSTEREOSPEECH
+#endif
+
 #define HYBRID_RESOLUTION 141
 #define HYBRID_RESOLUTION_USAC 77
 #define MAX_NRG_COMP_RATIO 1.e-5f
+#define LIMIT(x) (((x) > 1) ? 1 : ((x) < 0) ? 0 \
+                                            : (x))
+#define DB_TO_LINEAR(x) ((float)pow(10.0f, (x) / 20.0f))
+
+#define COSF(x) ((float)cos(x))
+#define ACOSF(x) ((float)acos(x))
+#define SINF(x) ((float)sin(x))
+#define TANF(x) ((float)tan(x))
+#define ATANF(x) ((float)atan(x))
+#define SQRTF(x) ((float)sqrt(x))
+#define LOGF(x) ((float)log(x))
+#define POWF(x, y) ((float)pow((x), (y)))
 
 static HANDLE_ERROR_INFO paramextract_calculateUsacDmx(HANDLE_TTO_BOX hTtoBox,
                                                        float **ppHybridDataReal1,
@@ -213,8 +231,6 @@
   float epsilonFloat;
   int nTimeSlotsMax;
 
-  int bKorSpeech;
-
 } TTO_BOX;
 
 static const int subband2Parameter4[HYBRID_RESOLUTION] = {
@@ -728,22 +744,23 @@
   return iccCorrelationCoherenceBorder;
 }
 
-static void alignParameterBandsWithSbrXover(int *pSubband2ParameterAnalysisIndex, int nHybBandsCore) {
-  int n;
-  for (n = nHybBandsCore - 1; n > 0; n--) {
-    if (pSubband2ParameterAnalysisIndex[n] != pSubband2ParameterAnalysisIndex[n - 1]) {
-      pSubband2ParameterAnalysisIndex[n] = pSubband2ParameterAnalysisIndex[n - 1];
-    } else {
-      break;
-    }
+static void alignParameterBandsWithSbrXover(int *pSubband2ParameterAnalysisIndex, const int nHybBandsCore, const int nParamBands) {
+  int lastSubband = nHybBandsCore - 1;
+
+  if ((pSubband2ParameterAnalysisIndex[lastSubband] != pSubband2ParameterAnalysisIndex[lastSubband - 1]) &&
+      (pSubband2ParameterAnalysisIndex[lastSubband] == pSubband2ParameterAnalysisIndex[lastSubband + 1])) {
+    pSubband2ParameterAnalysisIndex[lastSubband] = pSubband2ParameterAnalysisIndex[lastSubband - 1];
   }
 
-  for (n = nHybBandsCore - 1; n < HYBRID_RESOLUTION_USAC; n++) {
-    if (pSubband2ParameterAnalysisIndex[nHybBandsCore - 1] == pSubband2ParameterAnalysisIndex[n + 1]) {
-      pSubband2ParameterAnalysisIndex[n + 1] = pSubband2ParameterAnalysisIndex[nHybBandsCore - 1] + 1;
-    } else {
-      break;
-    }
+  if (pSubband2ParameterAnalysisIndex[lastSubband] == nParamBands - 1) {
+    return;
+  }
+  int band = nHybBandsCore;
+  while (
+      (band < HYBRID_RESOLUTION_USAC) &&
+      (pSubband2ParameterAnalysisIndex[lastSubband] == pSubband2ParameterAnalysisIndex[band])) {
+    pSubband2ParameterAnalysisIndex[band] = pSubband2ParameterAnalysisIndex[lastSubband] + 1;
+    band++;
   }
 }
 
@@ -856,7 +873,7 @@
     if ((*hTtoBox)->bStereoSbr && (*hTtoBox)->bCalcResiduals) {
       memcpy((*hTtoBox)->pSubband2ParameterAnalysisIndex, (*hTtoBox)->pSubband2ParameterIndex, HYBRID_RESOLUTION_USAC * sizeof(int));
 
-      alignParameterBandsWithSbrXover((*hTtoBox)->pSubband2ParameterAnalysisIndex, (*hTtoBox)->nHybBandsCore);
+      alignParameterBandsWithSbrXover((*hTtoBox)->pSubband2ParameterAnalysisIndex, (*hTtoBox)->nHybBandsCore, (*hTtoBox)->nParameterBands);
     }
   }
 
@@ -1226,10 +1243,10 @@
   if (error == noError) {
     if (pIcc != NULL) {
       for (i = 0; i < correlationCoherenceBorder; i++) {
-        pIcc[i] = min(pProdReal[i] / (float)sqrt(pPwr1[i] * pPwr2[i]), 1.f);
+        pIcc[i] = min(pProdReal[i] / SQRTF(pPwr1[i] * pPwr2[i]), 1.f);
       }
       for (; i < nParamBand; i++) {
-        pIcc[i] = min((float)sqrt((pProdReal[i] * pProdReal[i] + pProdImag[i] * pProdImag[i]) / (pPwr1[i] * pPwr2[i])), 1.f);
+        pIcc[i] = min(SQRTF((pProdReal[i] * pProdReal[i] + pProdImag[i] * pProdImag[i]) / (pPwr1[i] * pPwr2[i])), 1.f);
       }
     } else {
       error = iisUtil_ERROR(CDI, "Invalid pointer to pIcc");
@@ -1243,57 +1260,6 @@
   return error;
 }
 
-static int koreanDetector(HANDLE_TTO_BOX hTtoBox, int numIpdBands, int speechFlag) {
-  int pb, i;
-  float iccCor[MAX_NUM_BINS] = {0};
-
-  const float maxIccThr = 0.51f;
-  const float maxIpdThr = -0.72f;
-  const float minCldThr = 3.33f;
-
-  float meanIcc = 0;
-  float meanIpd = 0;
-  float minAbsCld = 0;
-
-  int bKorSpeech;
-  const int nPrev = 10;
-
-  float *cld = hTtoBox->pCld;
-  float *icc = hTtoBox->pIcc;
-  float *ipd = hTtoBox->pIpd;
-
-  for (pb = 0; pb < numIpdBands; pb++) {
-    iccCor[pb] = icc[pb] * (float)cos(ipd[pb]);
-  }
-
-  meanIpd = (ipd[1] + ipd[2]) / 2;
-
-  meanIcc = (iccCor[2] + iccCor[3] + iccCor[4]) / 3;
-
-  minAbsCld = max(((float)fabs(cld[0]) + (float)fabs(cld[1])) / 2, ((float)fabs(cld[2]) + (float)fabs(cld[3])) / 2);
-
-  if ((speechFlag) &&
-      (meanIpd < maxIpdThr) &&
-      (meanIcc < maxIccThr) &&
-      (minAbsCld > minCldThr)) {
-    bKorSpeech = 1;
-  } else {
-    bKorSpeech = 0;
-  }
-
-  hTtoBox->prevResult[hTtoBox->frameCount] = bKorSpeech;
-  for (i = 0; i < nPrev; i++) {
-    if (hTtoBox->prevResult[i] == 0) {
-      bKorSpeech = 0;
-      break;
-    }
-  }
-
-  hTtoBox->frameCount++;
-  hTtoBox->frameCount = hTtoBox->frameCount % nPrev;
-  return bKorSpeech;
-}
-
 void QuantizeCoef(
     const float *input,
     const int nBands,
@@ -1352,17 +1318,17 @@
     const int nBands,
     const float *quantTable,
     const int idxOffset,
-    float *dequantOut) {
+    float *deQuantOut) {
   int band;
 
   for (band = 0; band < nBands; band++) {
-    dequantOut[band] = quantTable[input[band] + idxOffset];
+    deQuantOut[band] = quantTable[input[band] + idxOffset];
   }
 
   return;
 }
 
-HANDLE_ERROR_INFO CalculateCld(
+HANDLE_ERROR_INFO calculateCld(
     int const nParamBand,
     float const *const pPwr1,
     float const *const pPwr2,
@@ -1391,13 +1357,13 @@
   HANDLE_ERROR_INFO error = noError;
   int i;
 
-  if (pIpd == NULL) {
-    error = iisUtil_ERROR(CDI, "Invalid pointer to pIpd");
-  }
-
   if (error == noError) {
-    for (i = 0; i < nParamBand; i++) {
-      pIpd[i] = (float)atan2(pProdImag[i], pProdReal[i]);
+    if (pIpd != NULL) {
+      for (i = 0; i < nParamBand; i++) {
+        pIpd[i] = (float)atan2(pProdImag[i], pProdReal[i]);
+      }
+    } else {
+      error = iisUtil_ERROR(CDI, "Invalid pointer to pIpd");
     }
   }
 
@@ -1423,64 +1389,53 @@
 
 static void quantizeIpd(const float *input,
                         const int nBands,
-                        const int quantMode,
+                        int nQuantSteps,
                         int *quantOut) {
-  int nQuantSteps = getIpdQuantSteps(quantMode);
-  int pb;
+  int paramBand;
 
-  for (pb = 0; pb < nBands; pb++) {
-    float ipd = (float)fmod(input[pb] + 2 * PI, 2 * PI);
+  for (paramBand = 0; paramBand < nBands; paramBand++) {
+    float ipd = (float)fmod(input[paramBand] + 2 * PI, 2 * PI);
     float index = ipd * nQuantSteps / (2 * PI);
 
-    quantOut[pb] = (int)floor(index + 0.5f);
+    quantOut[paramBand] = (int)floor(index + 0.5f);
 
-    if (quantOut[pb] == nQuantSteps) {
-      quantOut[pb] = 0;
+    if (quantOut[paramBand] == nQuantSteps) {
+      quantOut[paramBand] = 0;
     }
   }
 }
 
 static void deQuantizeIpd(const int *input,
                           const int nBands,
-                          const int quantMode,
-                          float *dequantOut) {
-  int nQuantSteps = getIpdQuantSteps(quantMode);
-  int pb;
+                          const int nQuantSteps,
+                          float *deQuantOut) {
+  int paramBand;
 
-  for (pb = 0; pb < nBands; pb++) {
-    dequantOut[pb] = input[pb] * 2 * PI / nQuantSteps;
+  for (paramBand = 0; paramBand < nBands; paramBand++) {
+    deQuantOut[paramBand] = input[paramBand] * 2 * PI / nQuantSteps;
   }
 }
 
-static int avoidPredictionSingularityClassic(const float *pCld,
-                                             int *pCldIdx,
-                                             const int band) {
-  int requantize = 0;
-
-  if (pCldIdx[band] == 0) {
-    if (pCld[band] >= 0.0f) {
-      pCldIdx[band] = 1;
-    } else {
-      pCldIdx[band] = -1;
-    }
-    requantize = 1;
-  }
-
-  return requantize;
-}
-
 static void avoidPredictionSingularity(HANDLE_TTO_BOX hTtoBox,
                                        int *pCldIdx,
                                        int *pIccIdx,
                                        int *pIpdIdx) {
   int nPhaseBands = hTtoBox->nOttBandsPhase;
+  const float *pCld = hTtoBox->pCld;
   int antiPhase = getIpdQuantSteps(hTtoBox->bUseCoarseQuantIpd) / 2;
   int requantize = 0;
-  int pb;
+  int requantize_val = 1;
+  int paramBand;
 
-  for (pb = 0; pb < nPhaseBands; pb++) {
-    if ((pIccIdx[pb] == 0) && (pIpdIdx[pb] == antiPhase)) {
-      requantize |= avoidPredictionSingularityClassic(hTtoBox->pCld, pCldIdx, pb);
+  for (paramBand = 0; paramBand < nPhaseBands; paramBand++) {
+    if ((pIccIdx[paramBand] == 0) && (pIpdIdx[paramBand] == antiPhase)) {
+      if (pCldIdx[paramBand] == 0) {
+        pCldIdx[paramBand] = (pCld[paramBand] >= 0.0f) ? 1 : -1;
+        requantize_val = 1;
+      } else {
+        requantize_val = 0;
+      }
+      requantize |= requantize_val;
     }
   }
 
@@ -1489,9 +1444,6 @@
   }
 }
 
-#define LIMIT(x) (((x) > 1) ? 1 : ((x) < 0) ? 0 \
-                                            : (x))
-
 static int ipdDetector(HANDLE_TTO_BOX hTtoBox, float *pPwr1, float *pPwr2, int numIpdBands) {
   float *cld = hTtoBox->pCld;
   float *icc = hTtoBox->pIcc;
@@ -1531,7 +1483,7 @@
     rIcc = LIMIT((icc[i] - iccRelev0) / (iccRelev1 - iccRelev0));
 
     rIpd = LIMIT(((float)fabs(ipd[i]) - ipdRelev0) / (ipdRelev1 - ipdRelev0));
-    rIpd = (float)sqrt(rIpd);
+    rIpd = SQRTF(rIpd);
 
     rIpd = (rIpd + .1f) / 1.1f;
 
@@ -1542,7 +1494,6 @@
     tmp = rCld * rIcc * rIpd * rNrg;
     if (tmp > rMax) rMax = tmp;
   }
-
   result = hTtoBox->prevIpdDecision;
 
   if ((rAvg > thrAvgHigh) || (rMax > thrMaxHigh)) {
@@ -1561,13 +1512,11 @@
                                  int *pIpdIdx,
                                  int bUseBBCues) {
   int nPhaseBands = hTtoBox->nOttBandsPhase;
-  int nParamBands = hTtoBox->nParameterBands;
   int quantMode = hTtoBox->bUseCoarseQuantIpd;
   float *powerHybridData1 = hTtoBox->pPwrHybridData1;
   float *powerHybridData2 = hTtoBox->pPwrHybridData2;
   int dominantPhase = 1;
   int phaseMode = 0;
-  int pb;
 
   if (hTtoBox->ipdMode == IPDMODE_RESIDUAL) {
     avoidPredictionSingularity(hTtoBox, pCldIdx, pIccIdx, pIpdIdx);
@@ -1578,32 +1527,32 @@
   }
 
   if ((dominantPhase) && (nPhaseBands > 0)) {
-    switch (quantMode) {
-      case 0:
-        phaseMode = 3;
-        break;
-      case 1:
-        phaseMode = 2;
-        break;
+    if (quantMode == 0) {
+      phaseMode = 3;
+    } else if (quantMode == 1) {
+      phaseMode = 2;
     }
   } else {
-    float *iccCoh;
-    float *iccCor;
+    float *coherence;
+    float *correlation;
     float *ipd;
+    int paramBand;
+    int nParamBands = hTtoBox->nParameterBands;
+    int nQuantSteps = getIpdQuantSteps(quantMode);
 
     if (hTtoBox->bCalcResiduals) {
-      iccCoh = hTtoBox->pIccQuant;
-      iccCor = hTtoBox->pIcc;
+      coherence = hTtoBox->pIccQuant;
+      correlation = hTtoBox->pIcc;
       ipd = hTtoBox->pIpdQuant;
     } else {
-      iccCoh = hTtoBox->pIcc;
-      iccCor = hTtoBox->pIcc;
+      coherence = hTtoBox->pIcc;
+      correlation = hTtoBox->pIcc;
       ipd = hTtoBox->pIpd;
     }
 
-    for (pb = 0; pb < nPhaseBands; pb++) {
-      iccCor[pb] = iccCoh[pb] * (float)cos(ipd[pb]);
-      pIpdIdx[pb] = 0;
+    for (paramBand = 0; paramBand < nPhaseBands; paramBand++) {
+      correlation[paramBand] = coherence[paramBand] * COSF(ipd[paramBand]);
+      pIpdIdx[paramBand] = 0;
     }
 
     if (bUseBBCues) {
@@ -1618,31 +1567,31 @@
 
       QuantizeCoef(hTtoBox->pIcc, nParamBands, hTtoBox->pIccQuantTable, hTtoBox->nIccQuantOffset, hTtoBox->nIccQuantSteps, pIccIdx);
       deQuantizeCoef(pIccIdx, nParamBands, hTtoBox->pIccQuantTable, hTtoBox->nIccQuantOffset, hTtoBox->pIccQuant);
-      deQuantizeIpd(pIpdIdx, nParamBands, quantMode, hTtoBox->pIpdQuant);
+      deQuantizeIpd(pIpdIdx, nParamBands, nQuantSteps, hTtoBox->pIpdQuant);
     } else {
       QuantizeCoef(hTtoBox->pIcc, nPhaseBands, hTtoBox->pIccQuantTable, hTtoBox->nIccQuantOffset, hTtoBox->nIccQuantSteps, pIccIdx);
       deQuantizeCoef(pIccIdx, nPhaseBands, hTtoBox->pIccQuantTable, hTtoBox->nIccQuantOffset, hTtoBox->pIccQuant);
-      deQuantizeIpd(pIpdIdx, nPhaseBands, quantMode, hTtoBox->pIpdQuant);
+      deQuantizeIpd(pIpdIdx, nPhaseBands, nQuantSteps, hTtoBox->pIpdQuant);
     }
   }
 
   return phaseMode;
 }
 
-static void getClassicDownmixWeightsPar(int startBand,
-                                        int stopBand,
-                                        float *cld,
-                                        float *icc,
-                                        float maxWeight,
-                                        CPLX *cplxWeight1,
-                                        CPLX *cplxWeight2) {
+static void getDownmixWeightsPar(int startBand,
+                                 int stopBand,
+                                 float *cld,
+                                 float *icc,
+                                 float maxWeight,
+                                 CPLX *cplxWeight1,
+                                 CPLX *cplxWeight2) {
   int i;
 
   for (i = startBand; i < stopBand; i++) {
-    float cldLin = (float)pow(10.0f, cld[i] / 20.0f);
+    float cldLin = DB_TO_LINEAR(cld[i]);
     float cldLin21 = cldLin * cldLin + 1.0f;
 
-    cplxWeight1[i].real = (float)sqrt(cldLin21 / (cldLin21 + 2.0f * icc[i] * cldLin));
+    cplxWeight1[i].real = SQRTF(cldLin21 / (cldLin21 + 2.0f * icc[i] * cldLin));
     cplxWeight1[i].real = min(maxWeight, cplxWeight1[i].real);
     cplxWeight1[i].imag = 0.0f;
     cplxWeight2[i].real = cplxWeight1[i].real;
@@ -1663,11 +1612,11 @@
   float *prodHybridReal = hTtoBox->pProdHybridReal;
   float *prodHybridImag = hTtoBox->pProdHybridImag;
   float powerSum, prodAbs, ratio, gain1, gain2, powerDmx;
-  int i, pb;
+  int i, paramBand;
 
   for (i = 0; i < nHybridBands; i++) {
-    pb = hTtoBox->pSubband2ParameterIndex[i];
-    if ((pb < startBand) || (pb >= stopBand)) {
+    paramBand = hTtoBox->pSubband2ParameterIndex[i];
+    if ((paramBand < startBand) || (paramBand >= stopBand)) {
       continue;
     }
 
@@ -1675,9 +1624,9 @@
     prodAbs = prodHybridReal[i] * prodHybridReal[i] +
               prodHybridImag[i] * prodHybridImag[i];
     ratio = (powerSum + 2.0f * prodHybridReal[i]) /
-            (powerSum + 2.0f * (float)sqrt(prodAbs));
+            (powerSum + 2.0f * SQRTF(prodAbs));
 
-    gain2 = (float)pow(max(ratio, 0.0f), 0.25f);
+    gain2 = POWF(max(ratio, 0.0f), 0.25f);
     gain1 = 2.0f - gain2;
 
     powerDmx = gain1 * gain1 * powerHybrid1[i];
@@ -1686,20 +1635,18 @@
 
     powerSum = max(powerSum, FLOAT_EPSILON);
     powerDmx = max(powerDmx, MAX_NRG_COMP_RATIO * powerSum);
+    double power_rms = sqrt(powerSum / powerDmx);
 
-    cplxWeight1[i].real = (float)sqrt(powerSum / powerDmx);
-    cplxWeight2[i].real = cplxWeight1[i].real;
+    cplxWeight1[i].real = (float)(power_rms)*gain1;
+    cplxWeight2[i].real = (float)(power_rms)*gain2;
     cplxWeight1[i].imag = 0.0f;
     cplxWeight2[i].imag = 0.0f;
 
-    cplxWeight1[i].real *= gain1;
-    cplxWeight2[i].real *= gain2;
-
     if (cplxWeight3 != NULL) {
-      cplxWeight3[i].real = (float)(1.0f / (sqrt(powerSum / powerDmx)));
+      cplxWeight3[i].real = (float)(1.0f / power_rms);
     }
     if (cplxWeight4 != NULL) {
-      cplxWeight4[i].real = (float)(1.0f / (sqrt(powerSum / powerDmx)));
+      cplxWeight4[i].real = (float)(1.0f / power_rms);
     }
   }
 }
@@ -1717,16 +1664,14 @@
 
   for (i = startBand; i < stopBand; i++) {
     float tmp1, tmp2;
-    float cldLin, cldLin2, iccClip;
+    float cldLin2;
     float alphaR, alphaI;
-
-    cldLin = (float)pow(10.0f, cld[i] / 20.0f);
+    float cldLin = DB_TO_LINEAR(cld[i]);
     cldLin2 = cldLin * cldLin;
-    iccClip = max(-0.99f, icc[i]);
-    tmp1 = 2.0f * iccClip * cldLin;
-    tmp2 = cldLin2 + 1.0f + tmp1 * (float)cos(ipd[i]);
+    tmp1 = 2.0f * max(-0.99f, icc[i]) * cldLin;
+    tmp2 = cldLin2 + 1.0f + tmp1 * COSF(ipd[i]);
     alphaR = (1.0f - cldLin2) / tmp2;
-    alphaI = -tmp1 * (float)sin(ipd[i]) / tmp2;
+    alphaI = -tmp1 * SINF(ipd[i]) / tmp2;
 
     cplxWeight3[i].real = cplxWeight2[i].real + alphaR * cplxWeight1[i].real;
     cplxWeight3[i].imag = alphaI * cplxWeight1[i].real;
@@ -1744,43 +1689,91 @@
                                   CPLX *cplxWeight1,
                                   CPLX *cplxWeight2,
                                   CPLX *cplxWeight3,
-                                  CPLX *cplxWeight4) {
+                                  CPLX *cplxWeight4)
+
+{
   int i;
-  int pb;
+  int paramBand;
 
   for (i = 0; i < nHybridBands; i++) {
-    pb = hTtoBox->pSubband2ParameterIndex[i];
-    if ((pb < startBand) || (pb >= stopBand)) {
+    paramBand = hTtoBox->pSubband2ParameterIndex[i];
+    if ((paramBand < startBand) || (paramBand >= stopBand)) {
       continue;
     }
-    {
-      float resGain = 1.0f;
 
-      float max_inv_det = 1.2f;
-      float iid_lin = (float)(pow(10, (cld[pb] / 20.0f)));
-      float c_l = (float)(sqrt((iid_lin * iid_lin) / (1 + (iid_lin * iid_lin))));
-      float c_r = (float)(sqrt(1 / (1 + (iid_lin * iid_lin))));
-      float iccCorrLim = max(icc[pb], (1 / (max_inv_det * max_inv_det) - 1.0f) * (iid_lin + 1.0f / iid_lin) / 2.0f);
-      float alpha = (float)(0.5f * acos(iccCorrLim));
-      float beta = (float)(atan(tan(alpha) * (c_r - c_l) / (c_r + c_l)));
-      float H11 = (float)(c_l * cos(alpha + beta));
-      float H21 = (float)(c_r * cos(-alpha + beta));
-      float H12_res = max(0.5f, H11);
-      float H22_res = -max(0.5f, H21);
-      float w1 = cplxWeight1[i].real;
-      float w2 = cplxWeight2[i].real;
+    float resGain = 1.0f;
+    float cldLin = DB_TO_LINEAR(cld[paramBand]);
+    float max_inv_det = 1.2f;
+    float cldLin2 = (float)(cldLin * cldLin);
+    float c_l = SQRTF((cldLin2) / (1 + (cldLin2)));
+    float c_r = SQRTF(1 / (1 + (cldLin2)));
+    float iccCorrLim = max(icc[paramBand], (1 / (max_inv_det * max_inv_det) - 1.0f) * (cldLin + 1.0f / cldLin) / 2.0f);
+    float alpha = (float)(0.5f * acos(iccCorrLim));
+    float beta = ATANF(tan(alpha) * (c_r - c_l) / (c_r + c_l));
 
-      cplxWeight3[i].real *= resGain * (((1 - H11 * w1) / H12_res) - (H21 * w1 / H22_res)) / 2.0f;
-      cplxWeight3[i].imag = 0;
-      cplxWeight4[i].real *= resGain * (((1 - H21 * w2) / H22_res) - (H11 * w2 / H12_res)) / 2.0f;
-      cplxWeight4[i].imag = 0;
-    }
+    float H11 = (float)(c_l * cos(alpha + beta));
+    float H21 = (float)(c_r * cos(-alpha + beta));
+    float H12_res = max(0.5f, H11);
+    float H22_res = -max(0.5f, H21);
+    float w1 = cplxWeight1[i].real;
+    float w2 = cplxWeight2[i].real;
+
+    cplxWeight3[i].real *= resGain * (((1 - H11 * w1) / H12_res) - (H21 * w1 / H22_res)) / 2.0f;
+    cplxWeight3[i].imag = 0;
+    cplxWeight4[i].real *= resGain * (((1 - H21 * w2) / H22_res) - (H11 * w2 / H12_res)) / 2.0f;
+    cplxWeight4[i].imag = 0;
   }
 }
 
-static HANDLE_ERROR_INFO calculateTtoDownmixParamUsac(
-    HANDLE_TTO_BOX hTtoBox,
-    int nHybridBands) {
+static void getClassicWeights(HANDLE_TTO_BOX hTtoBox,
+                              int resBand,
+                              int stopBand,
+                              float *cld,
+                              float *icc,
+                              CPLX *cplxWeight1,
+                              CPLX *cplxWeight2,
+                              CPLX *cplxWeight3,
+                              CPLX *cplxWeight4) {
+  int paramBand;
+  const float maxWeight = 1.2f;
+  const float iccMin = 0.5f * (1.0f / (maxWeight * maxWeight) - 1.0f);
+  float alpha, beta;
+  float tmp1, tmp2, tmp3;
+  float cldLin1;
+  float iccLim;
+  float *cldRes = hTtoBox->pCldQuant;
+  float *iccRes = hTtoBox->pIccDownmixQuant;
+  ;
+  for (paramBand = 0; paramBand < stopBand; paramBand++) {
+    if (paramBand == resBand) {
+      cldRes = cld;
+      iccRes = icc;
+    }
+    float cldLin = DB_TO_LINEAR(cldRes[paramBand]);
+    cldLin1 = cldLin + 1.0f / cldLin;
+    tmp1 = iccMin * cldLin1;
+    iccLim = max(tmp1, iccRes[paramBand]);
+    tmp1 = SQRTF(cldLin / cldLin1);
+    tmp2 = 1.0f / SQRTF(cldLin * cldLin1);
+    tmp3 = 1.0f / (cplxWeight3[paramBand].real - cplxWeight4[paramBand].real);
+
+    alpha = 0.5f * ACOSF(iccLim);
+    beta = ATANF((TANF(alpha)) * (tmp2 - tmp1) / (tmp2 + tmp1));
+
+    cplxWeight1[paramBand].real = max(0.0f, tmp3);
+    cplxWeight2[paramBand].real = cplxWeight1[paramBand].real;
+    cplxWeight3[paramBand].real = (tmp2 * COSF(beta - alpha)) * cplxWeight1[paramBand].real;
+    cplxWeight4[paramBand].real = (-tmp1 * COSF(beta + alpha)) * cplxWeight1[paramBand].real;
+
+    cplxWeight3[paramBand].real *= 2.0f;
+    cplxWeight3[paramBand].imag *= 2.0f;
+    cplxWeight4[paramBand].real *= 2.0f;
+    cplxWeight4[paramBand].imag *= 2.0f;
+  }
+}
+
+static HANDLE_ERROR_INFO calculateTtoDownmixParamUsac(HANDLE_TTO_BOX hTtoBox,
+                                                      int nHybridBands) {
   HANDLE_ERROR_INFO error = noError;
 
   int nParamBands = hTtoBox->nParameterBands;
@@ -1801,6 +1794,7 @@
   CPLX *cplxWeight4 = hTtoBox->pCplxDmWeight4;
 
   int i;
+  float maxWeight = 1.2f;
 
   if (NULL == icc || NULL == cld || NULL == cplxWeight1 || NULL == cplxWeight2) {
     error = iisUtil_ERROR(CDI, "Parameter error.");
@@ -1812,8 +1806,6 @@
 
   if (noError == error) {
     if (bCalcResiduals) {
-      const float maxWeight = 1.2f;
-
       float *cldRes = cldQuant;
       float *iccRes = iccQuant;
       float *ipdRes = ipdQuant;
@@ -1822,72 +1814,41 @@
 
       if (hTtoBox->ipdMode != IPDMODE_NONE) {
         for (i = 0; i < nResidualBands; i++) {
-          correlation[i] = iccRes[i] * (float)cos(ipdRes[i]);
+          correlation[i] = iccRes[i] * COSF(ipdRes[i]);
         }
         coherence = iccRes;
         iccRes = correlation;
       }
 
       if (hTtoBox->ipdMode == IPDMODE_RESIDUAL) {
-        getClassicDownmixWeightsPar(0, nResidualBands, cldRes, iccRes, maxWeight, cplxWeight1, cplxWeight2);
+        getDownmixWeightsPar(0, nResidualBands, cldRes, iccRes, maxWeight, cplxWeight1, cplxWeight2);
         getResidualWeightsPar(0, nResidualBands, cldRes, coherence, ipdRes, cplxWeight1, cplxWeight2, cplxWeight3, cplxWeight4);
 
-        if (hTtoBox->downmixType == DOWNMIXTYPE_CLASSICMPS) {
-          getClassicDownmixWeightsPar(nResidualBands, nParamBands, cld, icc, maxWeight, cplxWeight1, cplxWeight2);
-          getResidualWeightsPar(nResidualBands, nParamBands, cld, icc, ipd, cplxWeight1, cplxWeight2, cplxWeight3, cplxWeight4);
-        } else if (hTtoBox->downmixType == DOWNMIXTYPE_SIMPLIFIED_ABOVE_RESIDUAL) {
-          getCoherentDownmixWeightsHyb(hTtoBox, nHybridBands, nResidualBands, nParamBands, cplxWeight1, cplxWeight2, cplxWeight3, cplxWeight4);
-          getResidualWeightsHyb(hTtoBox, nHybridBands, nResidualBands, nParamBands, cld, icc, cplxWeight1, cplxWeight2, cplxWeight3, cplxWeight4);
-        }
+        switch (hTtoBox->downmixType) {
+          case DOWNMIXTYPE_CLASSICMPS:
+            getDownmixWeightsPar(nResidualBands, nParamBands, cld, icc, maxWeight, cplxWeight1, cplxWeight2);
+            getResidualWeightsPar(nResidualBands, nParamBands, cld, icc, ipd, cplxWeight1, cplxWeight2, cplxWeight3, cplxWeight4);
+            break;
 
+          case DOWNMIXTYPE_SIMPLIFIED_ABOVE_RESIDUAL:
+            getCoherentDownmixWeightsHyb(hTtoBox, nHybridBands, nResidualBands, nParamBands, cplxWeight1, cplxWeight2, cplxWeight3, cplxWeight4);
+            getResidualWeightsHyb(hTtoBox, nHybridBands, nResidualBands, nParamBands, cld, icc, cplxWeight1, cplxWeight2, cplxWeight3, cplxWeight4);
+            break;
+          default:
+            error = iisUtil_ERROR(CDI, "Invalid downmixType");
+            break;
+        }
       } else {
-        const float minIcc = 0.5f * (1.0f / (maxWeight * maxWeight) - 1.0f);
-
-        for (i = 0; i < nParamBands; i++) {
-          float alpha, beta;
-          float tmp1, tmp2;
-          float iccLim;
-          float cldLin;
-          float cldLin1;
-
-          if (i == nResidualBands) {
-            cldRes = cld;
-            iccRes = icc;
-          }
-
-          cldLin = (float)pow(10, cldRes[i] / 20.0f);
-          cldLin1 = cldLin + 1.0f / cldLin;
-
-          tmp1 = minIcc * cldLin1;
-          iccLim = max(tmp1, iccRes[i]);
-
-          tmp1 = (float)sqrt(cldLin / cldLin1);
-          tmp2 = 1.0f / (float)sqrt(cldLin * cldLin1);
-
-          alpha = 0.5f * (float)acos(iccLim);
-          beta = (float)atan(((float)tan(alpha)) * (tmp2 - tmp1) / (tmp2 + tmp1));
-
-          cplxWeight3[i].real = tmp2 * (float)cos(beta - alpha);
-          cplxWeight4[i].real = -tmp1 * (float)cos(beta + alpha);
-
-          cplxWeight1[i].real = 1.0f / (cplxWeight3[i].real - cplxWeight4[i].real);
-          cplxWeight1[i].real = max(0.0f, cplxWeight1[i].real);
-          cplxWeight2[i].real = cplxWeight1[i].real;
-          cplxWeight3[i].real *= cplxWeight1[i].real;
-          cplxWeight4[i].real *= cplxWeight1[i].real;
-
-          cplxWeight3[i].real *= 2.0f;
-          cplxWeight3[i].imag *= 2.0f;
-          cplxWeight4[i].real *= 2.0f;
-          cplxWeight4[i].imag *= 2.0f;
-        }
+        getClassicWeights(hTtoBox, nResidualBands, nParamBands, cld, icc, cplxWeight1, cplxWeight2, cplxWeight3, cplxWeight4);
       }
     } else {
-      const float maxWeight = (hTtoBox->ipdMode == IPDMODE_RESIDUAL) ? 1.2f : 2.0f;
+      if (hTtoBox->ipdMode != IPDMODE_RESIDUAL) {
+        maxWeight = 2.0f;
+      }
 
       switch (hTtoBox->downmixType) {
         case DOWNMIXTYPE_CLASSICMPS:
-          getClassicDownmixWeightsPar(0, nParamBands, cld, icc, maxWeight, cplxWeight1, cplxWeight2);
+          getDownmixWeightsPar(0, nParamBands, cld, icc, maxWeight, cplxWeight1, cplxWeight2);
           break;
         case DOWNMIXTYPE_SIMPLIFIED_ABOVE_RESIDUAL:
         case DOWNMIXTYPE_SIMPLIFIED:
@@ -1901,18 +1862,14 @@
 
     if ((hTtoBox->downmixType != DOWNMIXTYPE_SIMPLIFIED) && hTtoBox->bInterpolateDownmix) {
       for (i = nHybridBands - 1; i >= 0; i--) {
-        int pb = hTtoBox->pSubband2ParameterIndex[i];
+        int paramBand = hTtoBox->pSubband2ParameterIndex[i];
 
-        if (hTtoBox->downmixType != DOWNMIXTYPE_SIMPLIFIED_ABOVE_RESIDUAL || nResidualBands > pb) {
-          cplxWeight1[i].real = cplxWeight1[pb].real;
-          cplxWeight1[i].imag = cplxWeight1[pb].imag;
-          cplxWeight2[i].real = cplxWeight2[pb].real;
-          cplxWeight2[i].imag = cplxWeight2[pb].imag;
+        if (hTtoBox->downmixType != DOWNMIXTYPE_SIMPLIFIED_ABOVE_RESIDUAL || nResidualBands > paramBand) {
+          cplxWeight1[i] = cplxWeight1[paramBand];
+          cplxWeight2[i] = cplxWeight2[paramBand];
           if (bCalcResiduals) {
-            cplxWeight3[i].real = cplxWeight3[pb].real;
-            cplxWeight3[i].imag = cplxWeight3[pb].imag;
-            cplxWeight4[i].real = cplxWeight4[pb].real;
-            cplxWeight4[i].imag = cplxWeight4[pb].imag;
+            cplxWeight3[i] = cplxWeight3[paramBand];
+            cplxWeight4[i] = cplxWeight4[paramBand];
           }
         }
       }
@@ -1922,18 +1879,6 @@
   return error;
 }
 
-int GetbKorSpeech(HANDLE_TTO_BOX *hTtoBox, int nOttBoxes) {
-  int bKorSpeech = 0;
-  int box;
-  for (box = 0; box < nOttBoxes; box++) {
-    bKorSpeech = hTtoBox[box]->bKorSpeech;
-    if (bKorSpeech) {
-      break;
-    }
-  }
-  return bKorSpeech;
-}
-
 HANDLE_ERROR_INFO ApplyTtoBox(
     HANDLE_TTO_BOX hTtoBox,
     int nTimeSlots,
@@ -1955,7 +1900,7 @@
     int *pbIccDiffPresent,
     int bUseBBCues,
     CLASSIC_MPS SPACETREE_MODE mode,
-    int speechFlag)
+    ABSTEREOSPEECH int speechFlag)
 
 {
   HANDLE_ERROR_INFO error = noError;
@@ -1964,6 +1909,8 @@
 
   if (hTtoBox != NULL) {
     int nParamBands = hTtoBox->nParameterBands;
+    int nResidualBands = hTtoBox->nResidualBands;
+
     float *powerHybridData1 = hTtoBox->pPwrHybridData1;
     float *powerHybridData2 = hTtoBox->pPwrHybridData2;
     float *prodHybridDataReal = hTtoBox->pProdHybridDataReal;
@@ -1975,23 +1922,15 @@
     float *prodHybridImag = hTtoBox->pProdHybridImag;
 
     if (error == noError) {
-      if ((nHybridBands < 0) ||
-          (nHybridBands > hTtoBox->nHybridBandsMax)) {
+      if ((nHybridBands < 0) || (nHybridBands > hTtoBox->nHybridBandsMax)) {
         error = iisUtil_ERROR(CDI, "Invalid number nHybridBands.");
       }
-    }
-
-    if (error == noError) {
       if (nTimeSlots > hTtoBox->nTimeSlotsMax) {
         error = iisUtil_ERROR(CDI, "Invalid nTimeSlots.");
       }
     }
 
     if (error == noError) {
-      {
-        nParamBands = hTtoBox->nParameterBands;
-      }
-
       setFLOAT(hTtoBox->epsilonFloat, powerHybridData1, hTtoBox->nParameterBands);
       setFLOAT(hTtoBox->epsilonFloat, powerHybridData2, hTtoBox->nParameterBands);
       setFLOAT(hTtoBox->epsilonFloat, prodHybridDataReal, hTtoBox->nParameterBands);
@@ -2010,7 +1949,7 @@
           (ppHybridDataImag2 != NULL)) {
         for (j = 0; j < nHybridBands; j++) {
           int paramIndex = hTtoBox->pSubband2ParameterIndex[j];
-          float imagPartSign = (float)hTtoBox->pSubbandImagSign[j];
+          float imagSign = (float)hTtoBox->pSubbandImagSign[j];
 
           for (i = 0; i < nTimeSlots; i++) {
             if ((ppHybridDataReal1[i] != NULL) &&
@@ -2030,8 +1969,8 @@
                          ppHybridDataImag2[i][j] * ppHybridDataImag2[i][j];
                 power12real = ppHybridDataReal1[i][j] * ppHybridDataReal2[i][j] +
                               ppHybridDataImag1[i][j] * ppHybridDataImag2[i][j];
-                power12imag = imagPartSign * ppHybridDataImag1[i][j] * ppHybridDataReal2[i][j] -
-                              ppHybridDataReal1[i][j] * imagPartSign * ppHybridDataImag2[i][j];
+                power12imag = imagSign * ppHybridDataImag1[i][j] * ppHybridDataReal2[i][j] -
+                              ppHybridDataReal1[i][j] * imagSign * ppHybridDataImag2[i][j];
 
                 powerHybrid1[j] += power1;
                 powerHybrid2[j] += power2;
@@ -2049,8 +1988,8 @@
                                                 ppHybridDataImag2[i][j] * ppHybridDataImag2[i][j];
                 prodHybridDataReal[paramIndex] += ppHybridDataReal1[i][j] * ppHybridDataReal2[i][j] +
                                                   ppHybridDataImag1[i][j] * ppHybridDataImag2[i][j];
-                prodHybridDataImag[paramIndex] += imagPartSign * ppHybridDataImag1[i][j] * ppHybridDataReal2[i][j] -
-                                                  ppHybridDataReal1[i][j] * imagPartSign * ppHybridDataImag2[i][j];
+                prodHybridDataImag[paramIndex] += imagSign * ppHybridDataImag1[i][j] * ppHybridDataReal2[i][j] -
+                                                  ppHybridDataReal1[i][j] * imagSign * ppHybridDataImag2[i][j];
               }
             } else {
               error = iisUtil_ERROR(CDI, "Invalid pointer");
@@ -2063,25 +2002,23 @@
       }
     }
 
-    if (!hTtoBox->bCalcNoIcc) {
-      SAFECALL(error,
-               calculateIcc(nParamBands, hTtoBox->iccCorrelationCoherenceBorder, powerHybridData1, powerHybridData2, prodHybridDataReal, prodHybridDataImag, hTtoBox->pIcc));
-    }
-
     SAFECALL(error, calculateIcc(nParamBands, nParamBands, powerHybridData1, powerHybridData2, prodHybridDataReal, prodHybridDataImag, hTtoBox->pIccDownmix));
 
     if (!hTtoBox->bCalcNoIcc) {
-      if ((hTtoBox->ipdMode != IPDMODE_NONE) && hTtoBox->bCalcResiduals) {
-        int pb;
+      SAFECALL(error,
+               calculateIcc(nParamBands, hTtoBox->iccCorrelationCoherenceBorder, powerHybridData1, powerHybridData2, prodHybridDataReal, prodHybridDataImag, hTtoBox->pIcc));
 
-        for (pb = 0; pb < hTtoBox->nResidualBands; pb++) {
-          hTtoBox->pIccDownmix[pb] = hTtoBox->pIcc[pb];
+      if ((hTtoBox->ipdMode != IPDMODE_NONE) && hTtoBox->bCalcResiduals) {
+        int paramBand;
+
+        for (paramBand = 0; paramBand < nResidualBands; paramBand++) {
+          hTtoBox->pIccDownmix[paramBand] = hTtoBox->pIcc[paramBand];
         }
       }
     }
 
     {
-      SAFECALL(error, CalculateCld(nParamBands, powerHybridData1, powerHybridData2, hTtoBox->pCld));
+      SAFECALL(error, calculateCld(nParamBands, powerHybridData1, powerHybridData2, hTtoBox->pCld));
     }
 
     if (hTtoBox->ipdMode != IPDMODE_NONE) {
@@ -2089,32 +2026,31 @@
     }
 
     if (error == noError) {
-      hTtoBox->bKorSpeech = koreanDetector(hTtoBox, hTtoBox->nOttBandsPhase, speechFlag);
-
       if (hTtoBox->bStereoSbr && hTtoBox->bCalcResiduals) {
-        int nParamBandsCore;
-        int pb;
-        for (pb = 0; pb < nHybridBands; pb++) {
-          int paramIndex = hTtoBox->pSubband2ParameterIndex[pb];
-          int paramIndexAna = hTtoBox->pSubband2ParameterAnalysisIndex[pb];
+        int paramBand;
+        for (paramBand = 0; paramBand < nHybridBands; paramBand++) {
+          int paramIndex = hTtoBox->pSubband2ParameterIndex[paramBand];
+          int paramAnalysisIdx = hTtoBox->pSubband2ParameterAnalysisIndex[paramBand];
 
-          if (paramIndexAna < paramIndex) {
-            hTtoBox->pIcc[paramIndex] = hTtoBox->pIcc[paramIndexAna];
-            hTtoBox->pIccDownmix[paramIndex] = hTtoBox->pIccDownmix[paramIndexAna];
-            hTtoBox->pCld[paramIndex] = hTtoBox->pCld[paramIndexAna];
-            hTtoBox->pIpd[paramIndex] = hTtoBox->pIpd[paramIndexAna];
+          if (paramAnalysisIdx < paramIndex) {
+            hTtoBox->pIcc[paramIndex] = hTtoBox->pIcc[paramAnalysisIdx];
+            hTtoBox->pIccDownmix[paramIndex] = hTtoBox->pIccDownmix[paramAnalysisIdx];
+            hTtoBox->pCld[paramIndex] = hTtoBox->pCld[paramAnalysisIdx];
+            hTtoBox->pIpd[paramIndex] = hTtoBox->pIpd[paramAnalysisIdx];
           }
         }
 
+        int nParamBandsCore;
         nParamBandsCore = hTtoBox->pSubband2ParameterIndex[hTtoBox->nHybBandsCore] + 1;
-
+        float iccLastCore = hTtoBox->pIcc[nParamBandsCore - 1];
+        float cldLastCore = hTtoBox->pCld[nParamBandsCore - 1];
+        float ipdLastCore = hTtoBox->pIpd[nParamBandsCore - 1];
         for (i = nParamBandsCore; i < nParamBands; i++) {
-          hTtoBox->pIcc[i] = hTtoBox->pIcc[i - 1];
-          hTtoBox->pCld[i] = hTtoBox->pCld[i - 1];
+          hTtoBox->pIcc[i] = iccLastCore;
+          hTtoBox->pCld[i] = cldLastCore;
         }
-
         for (i = nParamBandsCore; i < hTtoBox->nOttBandsPhase; i++) {
-          hTtoBox->pIpd[i] = hTtoBox->pIpd[i - 1];
+          hTtoBox->pIpd[i] = ipdLastCore;
         }
       }
 
@@ -2133,7 +2069,7 @@
           }
           hTtoBox->pIccDownmix[0] /= (float)nParamBands;
 
-          for (i = 1; i < hTtoBox->nResidualBands; i++) {
+          for (i = 1; i < nResidualBands; i++) {
             hTtoBox->pIccDownmix[i] = hTtoBox->pIccDownmix[0];
           }
         }
@@ -2173,7 +2109,6 @@
         }
       }
     }
-
     if (error == noError) {
       if (!hTtoBox->bCalcNoIcc) {
         if (pbIccQuantCoarse != NULL) {
@@ -2206,16 +2141,17 @@
     if (error == noError && hTtoBox->bUsac212) {
       if (hTtoBox->ipdMode != IPDMODE_NONE) {
         if (pIpdIdx != NULL) {
-          quantizeIpd(hTtoBox->pIpd, hTtoBox->nOttBandsPhase, hTtoBox->bUseCoarseQuantIpd, pIpdIdx);
-          deQuantizeIpd(pIpdIdx, hTtoBox->nOttBandsPhase, hTtoBox->bUseCoarseQuantIpd, hTtoBox->pIpdQuant);
+          int nQuantSteps = getIpdQuantSteps(hTtoBox->bUseCoarseQuantIpd);
+          quantizeIpd(hTtoBox->pIpd, hTtoBox->nOttBandsPhase, nQuantSteps, pIpdIdx);
+          deQuantizeIpd(pIpdIdx, hTtoBox->nOttBandsPhase, nQuantSteps, hTtoBox->pIpdQuant);
           *bsPhaseMode = applyPhaseCorrections(hTtoBox, pCldIdx, pIccIdx, pIpdIdx, bUseBBCues);
+
           *numBinsIPD = hTtoBox->nOttBandsPhase;
         } else {
           error = iisUtil_ERROR(CDI, "Invalid pointer to pIpdIdx.");
         }
       }
     }
-
     if (error == noError && hTtoBox->bUsac212) {
       if (!hTtoBox->bCalcNoIcc) {
         if (noError != (error = calculateTtoDownmixParamUsac(hTtoBox, nHybridBands))) {
@@ -2318,8 +2254,9 @@
                        int nHybridBands,
                        TTO_MIX_MATRIX *pDownmix) {
   HANDLE_ERROR_INFO error = noError;
-
-  if (hTtoBox != NULL) {
+  if (hTtoBox == NULL) {
+    error = iisUtil_ERROR(CDI, "Invalid handle hTtoBox");
+  } else {
     int bCalcResiduals = hTtoBox->bCalcResiduals;
 
     CPLX *cplxWeight1 = hTtoBox->pCplxDmWeight1;
@@ -2327,40 +2264,36 @@
     CPLX *cplxWeight3 = hTtoBox->pCplxDmWeight3;
     CPLX *cplxWeight4 = hTtoBox->pCplxDmWeight4;
 
-    int hb;
+    int hybBand;
 
     if ((NULL == cplxWeight1) || (NULL == cplxWeight2)) {
-      error = iisUtil_ERROR(CDI, "Parameter error.");
+      error = iisUtil_ERROR(CDI, "Invalid parameter cplxWeight1/2.");
     }
 
     if (bCalcResiduals && ((NULL == cplxWeight3) || (NULL == cplxWeight4))) {
-      error = iisUtil_ERROR(CDI, "Parameter error.");
+      error = iisUtil_ERROR(CDI, "Invalid parameter cplxWeight3/4.");
     }
-
-    if (noError == error) {
-      for (hb = 0; hb < nHybridBands; hb++) {
-        pDownmix[hb].m[0][0].real = cplxWeight1[hb].real;
-        pDownmix[hb].m[0][0].imag = cplxWeight1[hb].imag;
-        pDownmix[hb].m[0][1].real = cplxWeight2[hb].real;
-        pDownmix[hb].m[0][1].imag = cplxWeight2[hb].imag;
+    if (error == noError) {
+      for (hybBand = 0; hybBand < nHybridBands; hybBand++) {
+        pDownmix[hybBand].m[0][0].real = cplxWeight1[hybBand].real;
+        pDownmix[hybBand].m[0][0].imag = cplxWeight1[hybBand].imag;
+        pDownmix[hybBand].m[0][1].real = cplxWeight2[hybBand].real;
+        pDownmix[hybBand].m[0][1].imag = cplxWeight2[hybBand].imag;
 
         if (bCalcResiduals) {
-          pDownmix[hb].m[1][0].real = cplxWeight3[hb].real;
-          pDownmix[hb].m[1][0].imag = cplxWeight3[hb].imag;
-          pDownmix[hb].m[1][1].real = cplxWeight4[hb].real;
-          pDownmix[hb].m[1][1].imag = cplxWeight4[hb].imag;
+          pDownmix[hybBand].m[1][0].real = cplxWeight3[hybBand].real;
+          pDownmix[hybBand].m[1][0].imag = cplxWeight3[hybBand].imag;
+          pDownmix[hybBand].m[1][1].real = cplxWeight4[hybBand].real;
+          pDownmix[hybBand].m[1][1].imag = cplxWeight4[hybBand].imag;
         } else {
-          pDownmix[hb].m[1][0].real = 0.0f;
-          pDownmix[hb].m[1][0].imag = 0.0f;
-          pDownmix[hb].m[1][1].real = 0.0f;
-          pDownmix[hb].m[1][1].imag = 0.0f;
+          pDownmix[hybBand].m[1][0].real = 0.0f;
+          pDownmix[hybBand].m[1][0].imag = 0.0f;
+          pDownmix[hybBand].m[1][1].real = 0.0f;
+          pDownmix[hybBand].m[1][1].imag = 0.0f;
         }
-
-        pDownmix[hb].infinity = 0;
+        pDownmix[hybBand].infinity = 0;
       }
     }
-  } else {
-    error = iisUtil_ERROR(CDI, "Invalid handle hTtoBox");
   }
 
   return error;
diff --git a/xhe-aac/spaceEnclib/src/space_paramextract.h b/xhe-aac/spaceEnclib/src/space_paramextract.h
index ec38d8b..257c02d 100644
--- a/xhe-aac/spaceEnclib/src/space_paramextract.h
+++ b/xhe-aac/spaceEnclib/src/space_paramextract.h
@@ -192,7 +192,7 @@
   int infinity;
 } TTO_MIX_MATRIX;
 
-HANDLE_ERROR_INFO CalculateCld(
+HANDLE_ERROR_INFO calculateCld(
     int const nParamBand,
     float const *const pPwr1,
     float const *const pPwr2,
@@ -274,6 +274,4 @@
 
 float getUniSteCld(const HANDLE_TTO_BOX hTtoBox, int parameterBand);
 
-int GetbKorSpeech(HANDLE_TTO_BOX *hTtoBox, int nOttBoxes);
-
 #endif
diff --git a/xhe-aac/spaceEnclib/src/space_tree.c b/xhe-aac/spaceEnclib/src/space_tree.c
index fb972ee..e78cbef 100644
--- a/xhe-aac/spaceEnclib/src/space_tree.c
+++ b/xhe-aac/spaceEnclib/src/space_tree.c
@@ -878,12 +878,6 @@
   return error;
 }
 
-int SpaceTree_GetbKorSpeech(HANDLE_SPACE_TREE hSpaceTree) {
-  int bKorSpeech = 0;
-  bKorSpeech = GetbKorSpeech(hSpaceTree->ttoBox, hSpaceTree->descr.nOttBoxes);
-  return bKorSpeech;
-}
-
 float SpaceTree_ParamBand2Freq(int nParamBands, int nSampleRate, int nParamBand, int nQmfBands) {
   return paramBand2Freq(nParamBands, nSampleRate, nParamBand, nQmfBands);
 }
diff --git a/xhe-aac/spaceEnclib/src/space_tree.h b/xhe-aac/spaceEnclib/src/space_tree.h
index a502e60..25296be 100644
--- a/xhe-aac/spaceEnclib/src/space_tree.h
+++ b/xhe-aac/spaceEnclib/src/space_tree.h
@@ -233,8 +233,6 @@
 
 float SpaceTree_GetUniSteCld(HANDLE_SPACE_TREE hSpaceTree, int parameterBand);
 
-int SpaceTree_GetbKorSpeech(HANDLE_SPACE_TREE hSpaceTree);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/xhe-aac/xHEAACEnc/src/xHEAACEncVersion.h b/xhe-aac/xHEAACEnc/src/xHEAACEncVersion.h
index 0157730..37e0153 100644
--- a/xhe-aac/xHEAACEnc/src/xHEAACEncVersion.h
+++ b/xhe-aac/xHEAACEnc/src/xHEAACEncVersion.h
@@ -96,4 +96,4 @@
 ----------------------------------------------------------------------------- */
 
 #define IIS_XHEAACENC_LIBRARY_VERSION "AOSP"
-#define IIS_XHEAACENC_VERSION_NUMBER "04.05.09"
+#define IIS_XHEAACENC_VERSION_NUMBER "1.0"