/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

/*
 * isac.c
 *
 * This C file contains the functions for the ISAC API
 *
 */

#include "isac.h"
#include "bandwidth_estimator.h"
#include "crc.h"
#include "entropy_coding.h"
#include "codec.h"
#include "structs.h"
#include "signal_processing_library.h"
#include "lpc_shape_swb16_tables.h"
#include "os_specific_inline.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#define BIT_MASK_DEC_INIT 0x0001
#define BIT_MASK_ENC_INIT 0x0002

#define LEN_CHECK_SUM_WORD8     4
#define MAX_NUM_LAYERS         10


/****************************************************************************
 * UpdatePayloadSizeLimit()
 *
 * Call this function to update the limit on the payload size. The limit on
 * payload size might change i) if a user ''directly changes the limit by
 * calling xxx_setMaxPayloadSize() or xxx_setMaxRate(), or ii) indirectly
 * when bandwidth is changing. The latter might be the result of bandwidth
 * adaptation, or direct change of the bottleneck in instantaneous mode.
 *
 * This function takes the current overall limit on payload, and translate it
 * to the limits on lower and upper-band. If the codec is in wideband mode
 * then the overall limit and the limit on the lower-band is the same.
 * Otherwise, a fraction of the limit should be allocated to lower-band
 * leaving some room for the upper-band bit-stream. That is why an update
 * of limit is required every time that the bandwidth is changing.
 *
 */
static void UpdatePayloadSizeLimit(
				   ISACMainStruct *instISAC)
{
  WebRtc_Word16 lim30MsPayloadBytes;
  WebRtc_Word16 lim60MsPayloadBytes;

  lim30MsPayloadBytes = WEBRTC_SPL_MIN(
				       (instISAC->maxPayloadSizeBytes),
				       (instISAC->maxRateBytesPer30Ms));

  lim60MsPayloadBytes = WEBRTC_SPL_MIN(
				       (instISAC->maxPayloadSizeBytes),
				       (instISAC->maxRateBytesPer30Ms << 1));

  // The only time that iSAC will have 60 ms
  // frame-size is when operating in wideband so
  // there is no upper-band bit-stream

  if(instISAC->bandwidthKHz == isac8kHz)
    {
      // at 8 kHz there is no upper-band bit-stream
      // therefore the lower-band limit is as the overall
      // limit.
      instISAC->instLB.ISACencLB_obj.payloadLimitBytes60 =
        lim60MsPayloadBytes;
      instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 =
        lim30MsPayloadBytes;
    }
  else
    {
      // when in super-wideband, we only have 30 ms frames
      // Do a rate allocation for the given limit.
      if(lim30MsPayloadBytes > 250)
	{
	  // 4/5 to lower-band the rest for upper-band
	  instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 =
	    (lim30MsPayloadBytes << 2) / 5;
	}
      else if(lim30MsPayloadBytes > 200)
	{
	  // for the interval of 200 to 250 the share of
	  // upper-band linearly grows from 20 to 50;
	  instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 =
	    (lim30MsPayloadBytes << 1) / 5 + 100;
	}
      else
	{
	  // allocate only 20 for upper-band
	  instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 =
	    lim30MsPayloadBytes - 20;
	}
      instISAC->instUB.ISACencUB_obj.maxPayloadSizeBytes =
        lim30MsPayloadBytes;
    }
}


/****************************************************************************
 * UpdateBottleneck()
 *
 * This function updates the bottleneck only if the codec is operating in
 * channel-adaptive mode. Furthermore, as the update of bottleneck might
 * result in an update of bandwidth, therefore, the bottlenech should be
 * updated just right before the first 10ms of a frame is pushed into encoder.
 *
 */
static void UpdateBottleneck(
			     ISACMainStruct *instISAC)
{
  // read the bottleneck from bandwidth estimator for the
  // first 10 ms audio. This way, if there is a change
  // in bandwidth upper and lower-band will be in sync.
  if((instISAC->codingMode == 0) &&
     (instISAC->instLB.ISACencLB_obj.buffer_index == 0) &&
     (instISAC->instLB.ISACencLB_obj.frame_nb == 0))
    {
      WebRtc_Word32 bottleneck;
      WebRtcIsac_GetUplinkBandwidth(&(instISAC->bwestimator_obj),
				    &bottleneck);

      // Adding hysteresis when increasing signal bandwidth
      if((instISAC->bandwidthKHz == isac8kHz)
	 && (bottleneck > 37000)
	 && (bottleneck < 41000))
	{
	  bottleneck = 37000;
	}

      // switching from 12 kHz to 16 kHz is not allowed at this revision
      // If we let this happen, we have to take care of buffer_index and
      // the last LPC vector.
      if((instISAC->bandwidthKHz != isac16kHz) &&
	 (bottleneck > 46000))
	{
	  bottleneck = 46000;
	}

      // we might need a rate allocation.
      if(instISAC->encoderSamplingRateKHz == kIsacWideband)
	{
	  // wideband is the only choise we have here.
	  instISAC->instLB.ISACencLB_obj.bottleneck =
	    (bottleneck > 32000)? 32000:bottleneck;
	  instISAC->bandwidthKHz = isac8kHz;
	}
      else
	{
	  // do the rate-allosation and get the new bandwidth.
	  enum ISACBandwidth bandwidth;
	  WebRtcIsac_RateAllocation(bottleneck,
				    &(instISAC->instLB.ISACencLB_obj.bottleneck),
				    &(instISAC->instUB.ISACencUB_obj.bottleneck),
				    &bandwidth);
	  if(bandwidth != isac8kHz)
	    {
	      instISAC->instLB.ISACencLB_obj.new_framelength = 480;
	    }
	  if(bandwidth != instISAC->bandwidthKHz)
	    {
	      // bandwidth is changing.
	      instISAC->bandwidthKHz = bandwidth;
	      UpdatePayloadSizeLimit(instISAC);
	      if(bandwidth == isac12kHz)
		{
		  instISAC->instLB.ISACencLB_obj.buffer_index = 0;
		}
	      // currently we don't let the bandwidth to switch to 16 kHz
	      // if in adaptive mode. If we let this happen, we have to take
	      // car of buffer_index and the last LPC vector.
	    }
	}
    }
}


/****************************************************************************
 * GetSendBandwidthInfo()
 *
 * This is called to get the bandwidth info. This info is the bandwidth and
 * and the jitter of 'there-to-here' channel, estimated 'here.' These info
 * is signaled in an in-band fashion to the otherside.
 *
 * The call to the bandwidth estimator trigers a recursive averaging which
 * has to be synchronized between encoder & decoder, therefore. The call to
 * BWE should be once per packet. As the BWE info is inserted into bit-stream
 * we need a valid info right before the encodeLB function is going to
 * generating a bit-stream. That is when lower-band buffer has already 20ms
 * of audio, and the 3rd block of 10ms is going to be injected into encoder.
 *
 * Inputs:
 *         - instISAC          : iSAC instance.
 *
 * Outputs:
 *         - bandwidthIndex    : an index which has to be encoded in
 *                               lower-band bit-stream, indicating the
 *                               bandwidth of there-to-here channel.
 *         - jitterInfo        : this indicates if the jitter is high
 *                               or low and it is encoded in upper-band
 *                               bit-stream.
 *
 */
static void GetSendBandwidthInfo(
				 ISACMainStruct* instISAC,
				 WebRtc_Word16*    bandwidthIndex,
				 WebRtc_Word16*    jitterInfo)
{
  if((instISAC->instLB.ISACencLB_obj.buffer_index ==
      (FRAMESAMPLES_10ms << 1)) &&
     (instISAC->instLB.ISACencLB_obj.frame_nb == 0))
    {
      /* bandwidth estimation and coding */
      WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj),
				       bandwidthIndex, jitterInfo, instISAC->decoderSamplingRateKHz);
    }
}


/****************************************************************************
 * WebRtcIsac_AssignSize(...)
 *
 * This function returns the size of the ISAC instance, so that the instance
 * can be created out side iSAC.
 *
 * Output:
 *        - sizeinbytes       : number of bytes needed to allocate for the
 *                              instance.
 *
 * Return value               : 0 - Ok
 *                             -1 - Error
 */
WebRtc_Word16 WebRtcIsac_AssignSize(
				   int *sizeInBytes)
{
  *sizeInBytes = sizeof(ISACMainStruct) * 2 / sizeof(WebRtc_Word16);
  return 0;
}


/****************************************************************************
 * WebRtcIsac_Assign(...)
 *
 * This function assignes the memory already created to the ISAC instance.
 *
 * Input:
 *        - ISAC_main_inst    : address of the pointer to the coder instance.
 *        - instISAC_Addr     : the already allocaded memeory, where we put the
 *                              iSAC struct
 *
 * Return value               : 0 - Ok
 *                             -1 - Error
 */
WebRtc_Word16 WebRtcIsac_Assign(
			       ISACStruct** ISAC_main_inst,
			       void*        instISAC_Addr)
{
  if(instISAC_Addr != NULL)
    {
      ISACMainStruct* instISAC = (ISACMainStruct*)instISAC_Addr;
      instISAC->errorCode = 0;
      instISAC->initFlag = 0;

      // Assign the address
      *ISAC_main_inst = (ISACStruct*)instISAC_Addr;

      // Default is wideband.
      instISAC->encoderSamplingRateKHz = kIsacWideband;
      instISAC->decoderSamplingRateKHz = kIsacWideband;
      instISAC->bandwidthKHz           = isac8kHz;
      return 0;
    }
  else
    {
      return -1;
    }
}


/****************************************************************************
 * WebRtcIsac_Create(...)
 *
 * This function creates an ISAC instance, which will contain the state
 * information for one coding/decoding channel.
 *
 * Input:
 *        - ISAC_main_inst    : address of the pointer to the coder instance.
 *
 * Return value               : 0 - Ok
 *                             -1 - Error
 */
WebRtc_Word16 WebRtcIsac_Create(
			       ISACStruct** ISAC_main_inst)
{
  ISACMainStruct* instISAC;

  instISAC = (ISACMainStruct*)WEBRTC_SPL_VNEW(ISACMainStruct, 1);
  *ISAC_main_inst = (ISACStruct*)instISAC;
  if(*ISAC_main_inst != NULL)
    {
      instISAC->errorCode = 0;
      instISAC->initFlag = 0;
      // Default is wideband
      instISAC->bandwidthKHz           = isac8kHz;
      instISAC->encoderSamplingRateKHz = kIsacWideband;
      instISAC->decoderSamplingRateKHz = kIsacWideband;
      return 0;
    }
  else
    {
      return -1;
    }
}


/****************************************************************************
 * WebRtcIsac_Free(...)
 *
 * This function frees the ISAC instance created at the beginning.
 *
 * Input:
 *        - ISAC_main_inst    : a ISAC instance.
 *
 * Return value               : 0 - Ok
 *                             -1 - Error
 */
WebRtc_Word16 WebRtcIsac_Free(
			     ISACStruct* ISAC_main_inst)
{
  ISACMainStruct* instISAC;

  instISAC = (ISACMainStruct*)ISAC_main_inst;
  WEBRTC_SPL_FREE(instISAC);
  return 0;
}


/****************************************************************************
 * EncoderInitLb(...) - internal function for initialization of
 *                                Lower Band
 * EncoderInitUb(...) - internal function for initialization of
 *                                Upper Band
 * WebRtcIsac_EncoderInit(...) - API function
 *
 * This function initializes a ISAC instance prior to the encoder calls.
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *        - CodingMode        : 0 -> Bit rate and frame length are automatically
 *                                 adjusted to available bandwidth on
 *                                 transmission channel, applicable just to
 *                                 wideband mode.
 *                              1 -> User sets a frame length and a target bit
 *                                 rate which is taken as the maximum
 *                                 short-term average bit rate.
 *
 * Return value               :  0 - Ok
 *                              -1 - Error
 */
static WebRtc_Word16 EncoderInitLb(
				   ISACLBStruct*             instLB,
				   WebRtc_Word16               codingMode,
				   enum IsacSamplingRate sampRate)
{
  WebRtc_Word16 statusInit = 0;
  int k;

  /* Init stream vector to zero */
  for(k=0; k < STREAM_SIZE_MAX_60; k++)
    {
      instLB->ISACencLB_obj.bitstr_obj.stream[k] = 0;
    }

  if((codingMode == 1) || (sampRate == kIsacSuperWideband))
    {
      // 30 ms frame-size if either in super-wideband or
      // instanteneous mode (I-mode)
      instLB->ISACencLB_obj.new_framelength = 480;
    }
  else
    {
      instLB->ISACencLB_obj.new_framelength = INITIAL_FRAMESAMPLES;
    }

  WebRtcIsac_InitMasking(&instLB->ISACencLB_obj.maskfiltstr_obj);
  WebRtcIsac_InitPreFilterbank(&instLB->ISACencLB_obj.prefiltbankstr_obj);
  WebRtcIsac_InitPitchFilter(&instLB->ISACencLB_obj.pitchfiltstr_obj);
  WebRtcIsac_InitPitchAnalysis(
			       &instLB->ISACencLB_obj.pitchanalysisstr_obj);


  instLB->ISACencLB_obj.buffer_index         = 0;
  instLB->ISACencLB_obj.frame_nb             = 0;
  /* default for I-mode */
  instLB->ISACencLB_obj.bottleneck           = 32000;
  instLB->ISACencLB_obj.current_framesamples = 0;
  instLB->ISACencLB_obj.s2nr                 = 0;
  instLB->ISACencLB_obj.payloadLimitBytes30  = STREAM_SIZE_MAX_30;
  instLB->ISACencLB_obj.payloadLimitBytes60  = STREAM_SIZE_MAX_60;
  instLB->ISACencLB_obj.maxPayloadBytes      = STREAM_SIZE_MAX_60;
  instLB->ISACencLB_obj.maxRateInBytes       = STREAM_SIZE_MAX_30;
  instLB->ISACencLB_obj.enforceFrameSize     = 0;
  /* invalid value prevents getRedPayload to
     run before encoder is called */
  instLB->ISACencLB_obj.lastBWIdx            = -1;
  return statusInit;
}

static WebRtc_Word16 EncoderInitUb(
				   ISACUBStruct* instUB,
				   WebRtc_Word16   bandwidth)
{
  WebRtc_Word16 statusInit = 0;
  int k;

  /* Init stream vector to zero */
  for(k = 0; k < STREAM_SIZE_MAX_60; k++)
    {
      instUB->ISACencUB_obj.bitstr_obj.stream[k] = 0;
    }

  WebRtcIsac_InitMasking(&instUB->ISACencUB_obj.maskfiltstr_obj);
  WebRtcIsac_InitPreFilterbank(&instUB->ISACencUB_obj.prefiltbankstr_obj);

  if(bandwidth == isac16kHz)
    {
      instUB->ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES;
    }
  else
    {
      instUB->ISACencUB_obj.buffer_index        = 0;
    }
  /* default for I-mode */
  instUB->ISACencUB_obj.bottleneck            = 32000;
  // These store the limits for the wideband + super-wideband bit-stream.
  instUB->ISACencUB_obj.maxPayloadSizeBytes    = STREAM_SIZE_MAX_30 << 1;
  // This has to be updated after each lower-band encoding to guarantee
  // a correct payload-limitation.
  instUB->ISACencUB_obj.numBytesUsed         = 0;
  memset(instUB->ISACencUB_obj.data_buffer_float, 0,
         (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES) * sizeof(float));

  memcpy(&(instUB->ISACencUB_obj.lastLPCVec),
         WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER);

  return statusInit;
}


WebRtc_Word16 WebRtcIsac_EncoderInit(
				    ISACStruct* ISAC_main_inst,
				    WebRtc_Word16 codingMode)
{
  ISACMainStruct *instISAC;
  WebRtc_Word16 status;

  instISAC = (ISACMainStruct*)ISAC_main_inst;

  if((codingMode != 0) && (codingMode != 1))
    {
      instISAC->errorCode = ISAC_DISALLOWED_CODING_MODE;
      return -1;
    }
  // default bottleneck
  instISAC->bottleneck = MAX_ISAC_BW;

  if(instISAC->encoderSamplingRateKHz == kIsacWideband)
    {
      instISAC->bandwidthKHz = isac8kHz;
      instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60;
      instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30;
    }
  else
    {
      instISAC->bandwidthKHz = isac16kHz;
      instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX;
      instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX;
    }

  // Channel-adaptive = 0; Instantaneous (Channel-independent) = 1;
  instISAC->codingMode = codingMode;

  WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj,
                                    instISAC->encoderSamplingRateKHz,
                                    instISAC->decoderSamplingRateKHz);

  WebRtcIsac_InitRateModel(&instISAC->rate_data_obj);
  /* default for I-mode */
  instISAC->MaxDelay = 10.0;

  status = EncoderInitLb(&instISAC->instLB, codingMode,
			 instISAC->encoderSamplingRateKHz);
  if(status < 0)
    {
      instISAC->errorCode = -status;
      return -1;
    }

  if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband)
    {
      // Initialize encoder filter-bank.
      memset(instISAC->analysisFBState1, 0,
	     FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32));
      memset(instISAC->analysisFBState2, 0,
	     FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32));

      status = EncoderInitUb(&(instISAC->instUB),
			     instISAC->bandwidthKHz);
      if(status < 0)
	{
	  instISAC->errorCode = -status;
	  return -1;
	}
    }
  // Initializtion is successful, set the flag
  instISAC->initFlag |= BIT_MASK_ENC_INIT;
  return 0;
}


/****************************************************************************
 * WebRtcIsac_Encode(...)
 *
 * This function encodes 10ms frame(s) and inserts it into a package.
 * Input speech length has to be 160 samples (10ms). The encoder buffers those
 * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
 * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *        - speechIn          : input speech vector.
 *
 * Output:
 *        - encoded           : the encoded data vector
 *
 * Return value:
 *                            : >0 - Length (in bytes) of coded data
 *                            :  0 - The buffer didn't reach the chosen
 *                                  frameSize so it keeps buffering speech
 *                                 samples.
 *                            : -1 - Error
 */
WebRtc_Word16 WebRtcIsac_Encode(
			       ISACStruct*        ISAC_main_inst,
			       const WebRtc_Word16* speechIn,
			       WebRtc_Word16*       encoded)
{
  ISACMainStruct* instISAC;
  ISACLBStruct*   instLB;
  ISACUBStruct*   instUB;

  float        inFrame[FRAMESAMPLES_10ms];
  WebRtc_Word16  speechInLB[FRAMESAMPLES_10ms];
  WebRtc_Word16  speechInUB[FRAMESAMPLES_10ms];
  WebRtc_Word16  streamLenLB;
  WebRtc_Word16  streamLenUB;
  WebRtc_Word16  streamLen;
  WebRtc_Word16  k;
  WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded;
  int          garbageLen;
  WebRtc_Word32  bottleneck;
  WebRtc_Word16  bottleneckIdx = 0;
  WebRtc_Word16  jitterInfo = 0;

  instISAC = (ISACMainStruct*)ISAC_main_inst;
  instLB = &(instISAC->instLB);
  instUB = &(instISAC->instUB);

  /* check if encoder initiated */
  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
      return -1;
    }

  if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband)
    {
      WebRtcSpl_AnalysisQMF(speechIn, speechInLB, speechInUB,
			     instISAC->analysisFBState1, instISAC->analysisFBState2);

      /* convert from fixed to floating point */
      for(k = 0; k < FRAMESAMPLES_10ms; k++)
	{
	  inFrame[k] = (float)speechInLB[k];
	}
    }
  else
    {
      for(k = 0; k < FRAMESAMPLES_10ms; k++)
	{
	  inFrame[k] = (float) speechIn[k];
	}
    }

  /* add some noise to avoid denormal numbers */
  inFrame[0] += (float)1.23455334e-3;
  inFrame[1] -= (float)2.04324239e-3;
  inFrame[2] += (float)1.90854954e-3;
  inFrame[9] += (float)1.84854878e-3;


  // This function will update the bottleneck if required
  UpdateBottleneck(instISAC);

  // Get the bandwith information which has to be sent to the other side
  GetSendBandwidthInfo(instISAC, &bottleneckIdx, &jitterInfo);

  //
  // ENCODE LOWER-BAND
  //
  streamLenLB = WebRtcIsac_EncodeLb(inFrame, &instLB->ISACencLB_obj,
                                    instISAC->codingMode, bottleneckIdx);

  if(streamLenLB < 0)
    {
      return -1;
    }

  if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband)
    {
      instUB = &(instISAC->instUB);

      // convert to float
      for(k = 0; k < FRAMESAMPLES_10ms; k++)
	{
	  inFrame[k] = (float) speechInUB[k];
	}

      /* add some noise to avoid denormal numbers */
      inFrame[0] += (float)1.23455334e-3;
      inFrame[1] -= (float)2.04324239e-3;
      inFrame[2] += (float)1.90854954e-3;
      inFrame[9] += (float)1.84854878e-3;

      // Tell to upper-band the number of bytes used so far.
      // This is for payload limitation.
      instUB->ISACencUB_obj.numBytesUsed = streamLenLB + 1 +
        LEN_CHECK_SUM_WORD8;

      //
      // ENCODE UPPER-BAND
      //
      switch(instISAC->bandwidthKHz)
	{
	case isac12kHz:
	  {
	    streamLenUB = WebRtcIsac_EncodeUb12(inFrame,
						&instUB->ISACencUB_obj,
						jitterInfo);
	    break;
	  }
	case isac16kHz:
	  {
	    streamLenUB = WebRtcIsac_EncodeUb16(inFrame,
						&instUB->ISACencUB_obj,
						jitterInfo);
	    break;
	  }
	case isac8kHz:
	  {
	    streamLenUB = 0;
	    break;
	  }
	default:
	  return -1;
	}

      if((streamLenUB < 0) &&
	 (streamLenUB != -ISAC_PAYLOAD_LARGER_THAN_LIMIT))
	{
	  // an error has happened but this is not the error due to a
	  // bit-stream larger than the limit
	  return -1;
	}

      if(streamLenLB == 0)
	{
	  return 0;
	}

      // One bite is allocated for the length. According to older decoders
      // so the length bit-stream plus one byte for size and
      // LEN_CHECK_SUM_WORD8 for the checksum should be less than or equal
      // to 255.
      if((streamLenUB > (255 - (LEN_CHECK_SUM_WORD8 + 1))) ||
	 (streamLenUB == -ISAC_PAYLOAD_LARGER_THAN_LIMIT))
	{
	  // we have got a too long bit-stream we skip the upper-band
	  // bit-stream for this frame.
	  streamLenUB = 0;
	}

      memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream,
	     streamLenLB);
      streamLen = streamLenLB;
      if(streamLenUB > 0)
	{
	  ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)(streamLenUB + 1 +
						       LEN_CHECK_SUM_WORD8);
	  memcpy(&ptrEncodedUW8[streamLenLB + 1],
		 instUB->ISACencUB_obj.bitstr_obj.stream, streamLenUB);
	  streamLen += ptrEncodedUW8[streamLenLB];
	}
      else
	{
	  ptrEncodedUW8[streamLenLB] = 0;
	}
    }
  else
    {
      if(streamLenLB == 0)
	{
	  return 0;
	}
      memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream,
	     streamLenLB);
      streamLenUB = 0;
      streamLen = streamLenLB;
    }

  // Add Garbage if required.
  WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj, &bottleneck);
  if(instISAC->codingMode == 0)
    {
      int          minBytes;
      int          limit;
      WebRtc_UWord8* ptrGarbage;

      instISAC->MaxDelay = (double)WebRtcIsac_GetUplinkMaxDelay(
								&instISAC->bwestimator_obj);

      /* update rate model and get minimum number of bytes in this packet */
      minBytes = WebRtcIsac_GetMinBytes(&(instISAC->rate_data_obj),
					streamLen, instISAC->instLB.ISACencLB_obj.current_framesamples,
					bottleneck, instISAC->MaxDelay, instISAC->bandwidthKHz);

      /* Make sure MinBytes does not exceed packet size limit */
      if(instISAC->bandwidthKHz == isac8kHz)
	{
	  if(instLB->ISACencLB_obj.current_framesamples == FRAMESAMPLES)
	    {
	      limit = instLB->ISACencLB_obj.payloadLimitBytes30;
	    }
	  else
	    {
	      limit = instLB->ISACencLB_obj.payloadLimitBytes60;
	    }
	}
      else
	{
	  limit = instUB->ISACencUB_obj.maxPayloadSizeBytes;
	}
      minBytes = (minBytes > limit)? limit:minBytes;

      /* Make sure we don't allow more than 255 bytes of garbage data.
	 We store the length of the garbage data in 8 bits in the bitstream,
	 255 is the max garbage length we can signal using 8 bits. */
      if((instISAC->bandwidthKHz == isac8kHz) ||
	 (streamLenUB == 0))
	{
	  ptrGarbage = &ptrEncodedUW8[streamLenLB];
	  limit = streamLen + 255;
	}
      else
	{
	  ptrGarbage = &ptrEncodedUW8[streamLenLB + 1 + streamLenUB];
	  limit = streamLen + (255 - ptrEncodedUW8[streamLenLB]);
	}
      minBytes = (minBytes > limit)? limit:minBytes;

      garbageLen = (minBytes > streamLen)? (minBytes - streamLen):0;

      /* Save data for creation of multiple bitstreams */
      //ISACencLB_obj->SaveEnc_obj.minBytes = MinBytes;

      /* if bitstream is too short, add garbage at the end */
      if(garbageLen > 0)
	{
	  for(k = 0; k < garbageLen; k++)
	    {
	      ptrGarbage[k] = (WebRtc_UWord8)(rand() & 0xFF);
	    }

	  // for a correct length of the upper-band bit-stream together
	  // with the garbage. Garbage is embeded in upper-band bit-stream.
	  //    That is the only way to preserve backward compatibility.
	  if((instISAC->bandwidthKHz == isac8kHz) ||
	     (streamLenUB == 0))
	    {
	      ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)garbageLen;
	    }
	  else
	    {
	      ptrEncodedUW8[streamLenLB] += (WebRtc_UWord8)garbageLen;
	      // write the length of the garbage at the end of the upper-band
	      // bit-stream, if exists. This helps for sanity check.
	      ptrEncodedUW8[streamLenLB + 1 + streamLenUB] = (WebRtc_UWord8)garbageLen;

	    }

	  streamLen += garbageLen;
	}
    }
  else
    {
      /* update rate model */
      WebRtcIsac_UpdateRateModel(&instISAC->rate_data_obj, streamLen,
				 instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck);
      garbageLen = 0;
    }

  // Generate CRC if required.
  if((instISAC->bandwidthKHz != isac8kHz) &&
     (streamLenUB > 0))
    {
      WebRtc_UWord32 crc;

      WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])),
			streamLenUB + garbageLen, &crc);
#ifndef WEBRTC_BIG_ENDIAN
      for(k = 0; k < LEN_CHECK_SUM_WORD8; k++)
	{
	  ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] =
	    (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF);
	}
#else
      memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc,
	     LEN_CHECK_SUM_WORD8);
#endif
    }

  return streamLen;
}


/******************************************************************************
 * WebRtcIsac_GetNewBitStream(...)
 *
 * This function returns encoded data, with the recieved bwe-index in the
 * stream. If the rate is set to a value less than bottleneck of codec
 * the new bistream will be re-encoded with the given target rate.
 * It should always return a complete packet, i.e. only called once
 * even for 60 msec frames.
 *
 * NOTE 1! This function does not write in the ISACStruct, it is not allowed.
 * NOTE 3! Rates larger than the bottleneck of the codec will be limited
 *         to the current bottleneck.
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *        - bweIndex          : Index of bandwidth estimate to put in new
 *                              bitstream
 *        - rate              : target rate of the transcoder is bits/sec.
 *                              Valid values are the accepted rate in iSAC,
 *                              i.e. 10000 to 56000.
 *
 * Output:
 *        - encoded           : The encoded data vector
 *
 * Return value               : >0 - Length (in bytes) of coded data
 *                              -1 - Error  or called in SWB mode
 *                                 NOTE! No error code is written to
 *                                 the struct since it is only allowed to read
 *                                 the struct.
 */
WebRtc_Word16 WebRtcIsac_GetNewBitStream(
					ISACStruct*  ISAC_main_inst,
					WebRtc_Word16  bweIndex,
					WebRtc_Word16  jitterInfo,
					WebRtc_Word32  rate,
					WebRtc_Word16* encoded,
					WebRtc_Word16  isRCU)
{
  Bitstr iSACBitStreamInst;   /* Local struct for bitstream handling */
  WebRtc_Word16 streamLenLB;
  WebRtc_Word16 streamLenUB;
  WebRtc_Word16 totalStreamLen;
  double gain2;
  double gain1;
  float scale;
  enum ISACBandwidth bandwidthKHz;
  double rateLB;
  double rateUB;
  WebRtc_Word32 currentBN;
  ISACMainStruct* instISAC;
  WebRtc_UWord8* encodedPtrUW8 = (WebRtc_UWord8*)encoded;
  WebRtc_UWord32 crc;
#ifndef WEBRTC_BIG_ENDIAN
  WebRtc_Word16  k;
#endif

  instISAC = (ISACMainStruct*)ISAC_main_inst;

  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      return -1;
    }

  // Get the bottleneck of this iSAC and limit the
  // given rate to the current bottleneck.
  WebRtcIsac_GetUplinkBw(ISAC_main_inst, &currentBN);
  if(rate > currentBN)
    {
      rate = currentBN;
    }

  if(WebRtcIsac_RateAllocation(rate, &rateLB, &rateUB, &bandwidthKHz) < 0)
    {
      return -1;
    }

  // Cannot transcode from 16 kHz to 12 kHz
  if((bandwidthKHz == isac12kHz) &&
     (instISAC->bandwidthKHz == isac16kHz))
    {
      return -1;
    }

  // These gains are in dB
  // gain for the given rate.
  gain1 = WebRtcIsac_GetSnr(rateLB,
			    instISAC->instLB.ISACencLB_obj.current_framesamples);
  // gain of this iSAC
  gain2 = WebRtcIsac_GetSnr(
			    instISAC->instLB.ISACencLB_obj.bottleneck,
			    instISAC->instLB.ISACencLB_obj.current_framesamples);

  // scale is the ratio of two gains in normal domain.
  scale = (float)pow(10, (gain1 - gain2) / 20.0);
  // change the scale if this is a RCU bit-stream.
  scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE):scale;

  streamLenLB = WebRtcIsac_EncodeStoredDataLb(
					      &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, &iSACBitStreamInst,
					      bweIndex, scale);

  if(streamLenLB < 0)
    {
      return -1;
    }

  /* convert from bytes to WebRtc_Word16 */
  memcpy(encoded, iSACBitStreamInst.stream, streamLenLB);

  if(bandwidthKHz == isac8kHz)
    {
      return streamLenLB;
    }

  totalStreamLen = streamLenLB;
  // super-wideband is always at 30ms.
  // These gains are in dB
  // gain for the given rate.
  gain1 = WebRtcIsac_GetSnr(rateUB, FRAMESAMPLES);
  // gain of this iSAC
  gain2 = WebRtcIsac_GetSnr(
			    instISAC->instUB.ISACencUB_obj.bottleneck, FRAMESAMPLES);

  // scale is the ratio of two gains in normal domain.
  scale = (float)pow(10, (gain1 - gain2) / 20.0);

  // change the scale if this is a RCU bit-stream.
  scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE_UB):scale;

  switch(instISAC->bandwidthKHz)
    {
    case isac12kHz:
      {
        streamLenUB = WebRtcIsac_EncodeStoredDataUb12(
						      &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj),
						      &iSACBitStreamInst, jitterInfo, scale);
        break;
      }
    case isac16kHz:
      {
        streamLenUB = WebRtcIsac_EncodeStoredDataUb16(
						      &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj),
						      &iSACBitStreamInst, jitterInfo, scale);
        break;
      }
    default:
      return -1;
    }

  if(streamLenUB < 0)
    {
      return -1;
    }

  if(streamLenUB + 1 + LEN_CHECK_SUM_WORD8 > 255)
    {
      return streamLenLB;
    }

  totalStreamLen = streamLenLB + streamLenUB + 1 + LEN_CHECK_SUM_WORD8;
  encodedPtrUW8[streamLenLB] = streamLenUB + 1 + LEN_CHECK_SUM_WORD8;

  memcpy(&encodedPtrUW8[streamLenLB+1], iSACBitStreamInst.stream,
         streamLenUB);

  WebRtcIsac_GetCrc((WebRtc_Word16*)(&(encodedPtrUW8[streamLenLB + 1])),
                    streamLenUB, &crc);
#ifndef WEBRTC_BIG_ENDIAN
  for(k = 0; k < LEN_CHECK_SUM_WORD8; k++)
    {
      encodedPtrUW8[totalStreamLen - LEN_CHECK_SUM_WORD8 + k] =
        (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF);
    }
#else
  memcpy(&encodedPtrUW8[streamLenLB + streamLenUB + 1], &crc,
         LEN_CHECK_SUM_WORD8);
#endif


  return totalStreamLen;
}


/****************************************************************************
 * DecoderInitLb(...) - internal function for initialization of
 *                                Lower Band
 * DecoderInitUb(...) - internal function for initialization of
 *                                Upper Band
 * WebRtcIsac_DecoderInit(...) - API function
 *
 * This function initializes a ISAC instance prior to the decoder calls.
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *
 * Return value
 *                            :  0 - Ok
 *                              -1 - Error
 */
static WebRtc_Word16 DecoderInitLb(
				   ISACLBStruct* instISAC)
{
  int i;
  /* Init stream vector to zero */
  for (i=0; i<STREAM_SIZE_MAX_60; i++)
    {
      instISAC->ISACdecLB_obj.bitstr_obj.stream[i] = 0;
    }

  WebRtcIsac_InitMasking(&instISAC->ISACdecLB_obj.maskfiltstr_obj);
  WebRtcIsac_InitPostFilterbank(
				&instISAC->ISACdecLB_obj.postfiltbankstr_obj);
  WebRtcIsac_InitPitchFilter(&instISAC->ISACdecLB_obj.pitchfiltstr_obj);

  return (0);
}

static WebRtc_Word16 DecoderInitUb(
				   ISACUBStruct* instISAC)
{
  int i;
  /* Init stream vector to zero */
  for (i = 0; i < STREAM_SIZE_MAX_60; i++)
    {
      instISAC->ISACdecUB_obj.bitstr_obj.stream[i] = 0;
    }

  WebRtcIsac_InitMasking(&instISAC->ISACdecUB_obj.maskfiltstr_obj);
  WebRtcIsac_InitPostFilterbank(
				&instISAC->ISACdecUB_obj.postfiltbankstr_obj);
  return (0);
}

WebRtc_Word16 WebRtcIsac_DecoderInit(
				    ISACStruct *ISAC_main_inst)
{
  ISACMainStruct* instISAC;

  instISAC = (ISACMainStruct*)ISAC_main_inst;

  if(DecoderInitLb(&instISAC->instLB) < 0)
    {
      return -1;
    }

  if(instISAC->decoderSamplingRateKHz == kIsacSuperWideband)
    {
      memset(instISAC->synthesisFBState1, 0,
	     FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32));
      memset(instISAC->synthesisFBState2, 0,
	     FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32));

      if(DecoderInitUb(&(instISAC->instUB)) < 0)
	{
	  return -1;
	}
    }

  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj,
					instISAC->encoderSamplingRateKHz,
					instISAC->decoderSamplingRateKHz);
    }

  instISAC->initFlag |= BIT_MASK_DEC_INIT;

  instISAC->resetFlag_8kHz = 0;

  return 0;
}


/****************************************************************************
 * WebRtcIsac_UpdateBwEstimate(...)
 *
 * This function updates the estimate of the bandwidth.
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *        - encoded           : encoded ISAC frame(s).
 *        - packet_size       : size of the packet.
 *        - rtp_seq_number    : the RTP number of the packet.
 *        - arr_ts            : the arrival time of the packet (from NetEq)
 *                              in samples.
 *
 * Return value               :  0 - Ok
 *                              -1 - Error
 */
WebRtc_Word16 WebRtcIsac_UpdateBwEstimate(
				  ISACStruct*         ISAC_main_inst,
				  const WebRtc_UWord16* encoded,
				  WebRtc_Word32         packet_size,
				  WebRtc_UWord16        rtp_seq_number,
				  WebRtc_UWord32        send_ts,
				  WebRtc_UWord32        arr_ts)
{
  ISACMainStruct *instISAC;
  Bitstr streamdata;
#ifndef WEBRTC_BIG_ENDIAN
  int k;
#endif
  WebRtc_Word16 err;

  /* typecast pointer to real structure */
  instISAC = (ISACMainStruct *)ISAC_main_inst;

  /* check if decoder initiated */
  if((instISAC->initFlag & BIT_MASK_DEC_INIT) !=
     BIT_MASK_DEC_INIT)
    {
      instISAC->errorCode = ISAC_DECODER_NOT_INITIATED;
      return -1;
    }

  if(packet_size <= 0)
    {
      /* return error code if the packet length is null */
      instISAC->errorCode = ISAC_EMPTY_PACKET;
      return -1;
    }

  streamdata.W_upper = 0xFFFFFFFF;
  streamdata.streamval = 0;
  streamdata.stream_index = 0;

#ifndef WEBRTC_BIG_ENDIAN
  for(k = 0; k < 10; k++)
    {
      streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >>
					       ((k&1) << 3)) & 0xFF);
    }
#else
  memcpy(streamdata.stream, encoded, 10);
#endif

  err = WebRtcIsac_EstimateBandwidth(&instISAC->bwestimator_obj, &streamdata,
                                     packet_size, rtp_seq_number, send_ts, arr_ts,
                                     instISAC->encoderSamplingRateKHz,
                                     instISAC->decoderSamplingRateKHz);

  if(err < 0)
    {
      /* return error code if something went wrong */
      instISAC->errorCode = -err;
      return -1;
    }

  return 0;
}

static WebRtc_Word16 Decode(
			    ISACStruct*         ISAC_main_inst,
			    const WebRtc_UWord16* encoded,
			    WebRtc_Word16         lenEncodedBytes,
			    WebRtc_Word16*        decoded,
			    WebRtc_Word16*        speechType,
			    WebRtc_Word16         isRCUPayload)
{
  /* number of samples (480 or 960), output from decoder
     that were actually used in the encoder/decoder
     (determined on the fly) */
  ISACMainStruct* instISAC;
  ISACUBDecStruct* decInstUB;
  ISACLBDecStruct*    decInstLB;

  WebRtc_Word16  numSamplesLB;
  WebRtc_Word16  numSamplesUB;
  WebRtc_Word16  speechIdx;
  float        outFrame[MAX_FRAMESAMPLES];
  WebRtc_Word16  outFrameLB[MAX_FRAMESAMPLES];
  WebRtc_Word16  outFrameUB[MAX_FRAMESAMPLES];
  WebRtc_Word16  numDecodedBytesLB;
  WebRtc_Word16  numDecodedBytesUB;
  WebRtc_Word16  lenEncodedLBBytes;
  WebRtc_Word16  validChecksum = 1;
  WebRtc_Word16  k;
  WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded;
  WebRtc_UWord16 numLayer;
  WebRtc_Word16  totSizeBytes;
  WebRtc_Word16  err;

  instISAC = (ISACMainStruct*)ISAC_main_inst;
  decInstUB = &(instISAC->instUB.ISACdecUB_obj);
  decInstLB = &(instISAC->instLB.ISACdecLB_obj);

  /* check if decoder initiated */
  if((instISAC->initFlag & BIT_MASK_DEC_INIT) !=
     BIT_MASK_DEC_INIT)
    {
      instISAC->errorCode = ISAC_DECODER_NOT_INITIATED;
      return -1;
    }

  if(lenEncodedBytes <= 0)
    {
      /* return error code if the packet length is null */
      instISAC->errorCode = ISAC_EMPTY_PACKET;
      return -1;
    }

  // the size of the rncoded lower-band is bounded by
  // STREAM_SIZE_MAX,
  // If a payload with the size larger than STREAM_SIZE_MAX
  // is received, it is not considered erroneous.
  lenEncodedLBBytes = (lenEncodedBytes > STREAM_SIZE_MAX)
    ?  STREAM_SIZE_MAX:lenEncodedBytes;

  // Copy to lower-band bit-stream structure
  memcpy(instISAC->instLB.ISACdecLB_obj.bitstr_obj.stream, ptrEncodedUW8,
         lenEncodedLBBytes);

  // Regardless of that the current codec is setup to work in
  // wideband or super-wideband, the decoding of the lower-band
  // has to be performed.
  numDecodedBytesLB = WebRtcIsac_DecodeLb(outFrame, decInstLB,
                                          &numSamplesLB, isRCUPayload);

  // Check for error
  if((numDecodedBytesLB < 0) ||
     (numDecodedBytesLB > lenEncodedLBBytes) ||
     (numSamplesLB > MAX_FRAMESAMPLES))
    {
      instISAC->errorCode = ISAC_LENGTH_MISMATCH;
      return -1;
    }

  // Error Check, we accept multi-layer bit-stream
  // This will limit number of iterations of the
  // while loop. Even withouut this the number of iterations
  // is limited.
  numLayer = 1;
  totSizeBytes = numDecodedBytesLB;
  while(totSizeBytes != lenEncodedBytes)
    {
      if((totSizeBytes > lenEncodedBytes) ||
	 (ptrEncodedUW8[totSizeBytes] == 0) ||
	 (numLayer > MAX_NUM_LAYERS))
	{
	  instISAC->errorCode = ISAC_LENGTH_MISMATCH;
	  return -1;
	}
      totSizeBytes += ptrEncodedUW8[totSizeBytes];
      numLayer++;
    }

  if(instISAC->decoderSamplingRateKHz == kIsacWideband)
    {
      for(k = 0; k < numSamplesLB; k++)
	{
	  if(outFrame[k] > 32767)
	    {
	      decoded[k] = 32767;
	    }
	  else if(outFrame[k] < -32768)
	    {
	      decoded[k] = -32768;
	    }
	  else
	    {
              decoded[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]);
	    }
	}
      numSamplesUB = 0;
    }
  else
    {
      WebRtc_UWord32 crc;
      // We don't accept larger than 30ms (480 samples at lower-band)
      // frame-size.
      for(k = 0; k < numSamplesLB; k++)
	{
	  if(outFrame[k] > 32767)
	    {
	      outFrameLB[k] = 32767;
	    }
	  else if(outFrame[k] < -32768)
	    {
	      outFrameLB[k] = -32768;
	    }
	  else
	    {
              outFrameLB[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]);
	    }
	}

      //numSamplesUB = numSamplesLB;

      // Check for possible error, and if upper-band stream exist.
      if(numDecodedBytesLB == lenEncodedBytes)
	{
	  // Decoding was successful. No super-wideband bitstream
	  // exists.
	  numSamplesUB = numSamplesLB;
	  memset(outFrameUB, 0, sizeof(WebRtc_Word16) *  numSamplesUB);

	  // Prepare for the potential increase of signal bandwidth
	  instISAC->resetFlag_8kHz = 2;
	}
      else
	{
	  // this includes the check sum and the bytes that stores the
	  // length
	  WebRtc_Word16 lenNextStream = ptrEncodedUW8[numDecodedBytesLB];

	  // Is this garbage or valid super-wideband bit-stream?
	  // Check if checksum is valid
	  if(lenNextStream <= (LEN_CHECK_SUM_WORD8 + 1))
	    {
	      // such a small second layer cannot be super-wideband layer.
	      // It must be a short garbage.
	      validChecksum = 0;
	    }
	  else
	    {
	      // Run CRC to see if the checksum match.
	      WebRtcIsac_GetCrc((WebRtc_Word16*)(
						 &ptrEncodedUW8[numDecodedBytesLB + 1]),
				lenNextStream - LEN_CHECK_SUM_WORD8 - 1, &crc);

	      validChecksum = 1;
	      for(k = 0; k < LEN_CHECK_SUM_WORD8; k++)
		{
		  validChecksum &= (((crc >> (24 - k * 8)) & 0xFF) ==
				    ptrEncodedUW8[numDecodedBytesLB + lenNextStream -
						  LEN_CHECK_SUM_WORD8 + k]);
		}
	    }

	  if(!validChecksum)
	    {
	      // this is a garbage, we have received a wideband
	      // bit-stream with garbage
	      numSamplesUB = numSamplesLB;
	      memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB);
	    }
	  else
	    {
	      // A valid super-wideband biststream exists.
	      enum ISACBandwidth bandwidthKHz;
	      WebRtc_Word32 maxDelayBit;

	      //instISAC->bwestimator_obj.incomingStreamSampFreq =
	      //    kIsacSuperWideband;
	      // If we have super-wideband bit-stream, we cannot
	      // have 60 ms frame-size.
	      if(numSamplesLB > FRAMESAMPLES)
		{
		  instISAC->errorCode = ISAC_LENGTH_MISMATCH;
		  return -1;
		}

	      // the rest of the bit-stream contains the upper-band
	      // bit-stream curently this is the only thing there,
	      // however, we might add more layers.

	      // Have to exclude one byte where the length is stored
	      // and last 'LEN_CHECK_SUM_WORD8' bytes where the
	      // checksum is stored.
	      lenNextStream -= (LEN_CHECK_SUM_WORD8 + 1);

	      memcpy(decInstUB->bitstr_obj.stream,
		     &ptrEncodedUW8[numDecodedBytesLB + 1], lenNextStream);

	      // THIS IS THE FIRST DECODING
	      decInstUB->bitstr_obj.W_upper      = 0xFFFFFFFF;
	      decInstUB->bitstr_obj.streamval    = 0;
	      decInstUB->bitstr_obj.stream_index = 0;

	      // Decode jitter infotmation
	      err = WebRtcIsac_DecodeJitterInfo(&decInstUB->bitstr_obj,
						&maxDelayBit);
	      // error check
	      if(err < 0)
		{
		  instISAC->errorCode = -err;
		  return -1;
		}

	      // Update jitter info which is in the upper-band bit-stream
	      // only if the encoder is in super-wideband. Otherwise,
	      // the jitter info is already embeded in bandwidth index
	      // and has been updated.
	      if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband)
		{
		  err = WebRtcIsac_UpdateUplinkJitter(
						      &(instISAC->bwestimator_obj), maxDelayBit);
		  if(err < 0)
		    {
		      instISAC->errorCode = -err;
		      return -1;
		    }
		}

	      // decode bandwidth information
	      err = WebRtcIsac_DecodeBandwidth(&decInstUB->bitstr_obj,
					       &bandwidthKHz);
	      if(err < 0)
		{
		  instISAC->errorCode = -err;
		  return -1;
		}

	      switch(bandwidthKHz)
		{
		case isac12kHz:
		  {
		    numDecodedBytesUB = WebRtcIsac_DecodeUb12(outFrame,
							      decInstUB, isRCUPayload);

		    // Hang-over for transient alleviation -
		    // wait two frames to add the upper band going up from 8 kHz
		    if (instISAC->resetFlag_8kHz > 0)
		      {
			if (instISAC->resetFlag_8kHz == 2)
			  {
			    // Silence first and a half frame
			    memset(outFrame, 0, MAX_FRAMESAMPLES *
				   sizeof(float));
			  }
			else
			  {
			    const float rampStep = 2.0f / MAX_FRAMESAMPLES;
			    float rampVal = 0;
			    memset(outFrame, 0, (MAX_FRAMESAMPLES>>1) *
				   sizeof(float));

			    // Ramp up second half of second frame
			    for(k = MAX_FRAMESAMPLES/2; k < MAX_FRAMESAMPLES; k++)
			      {
				outFrame[k] *= rampVal;
				rampVal += rampStep;
			      }
			  }
			instISAC->resetFlag_8kHz -= 1;
		      }

		    break;
		  }
		case isac16kHz:
		  {
		    numDecodedBytesUB = WebRtcIsac_DecodeUb16(outFrame,
							      decInstUB, isRCUPayload);
		    break;
		  }
		default:
		  return -1;
		}

	      // it might be less due to garbage.
	      if((numDecodedBytesUB != lenNextStream) &&
		 (numDecodedBytesUB != (lenNextStream - ptrEncodedUW8[
								      numDecodedBytesLB + 1 + numDecodedBytesUB])))
		{
		  instISAC->errorCode = ISAC_LENGTH_MISMATCH;
		  return -1;
		}

	      // If there is no error Upper-band always decodes
	      // 30 ms (480 samples)
	      numSamplesUB = FRAMESAMPLES;

	      // Convert to W16
	      for(k = 0; k < numSamplesUB; k++)
		{
		  if(outFrame[k] > 32767)
		    {
		      outFrameUB[k] = 32767;
		    }
		  else if(outFrame[k] < -32768)
		    {
		      outFrameUB[k] = -32768;
		    }
		  else
		    {
                      outFrameUB[k] = (WebRtc_Word16)WebRtcIsac_lrint(
                          outFrame[k]);
		    }
		}
	    }
	}

      speechIdx = 0;
      while(speechIdx < numSamplesLB)
	{
	  WebRtcSpl_SynthesisQMF(&outFrameLB[speechIdx],
				  &outFrameUB[speechIdx], &decoded[(speechIdx<<1)],
				  instISAC->synthesisFBState1, instISAC->synthesisFBState2);

	  speechIdx += FRAMESAMPLES_10ms;
	}
    }
  *speechType = 0;
  return (numSamplesLB + numSamplesUB);
}







/****************************************************************************
 * WebRtcIsac_Decode(...)
 *
 * This function decodes a ISAC frame. Output speech length
 * will be a multiple of 480 samples: 480 or 960 samples,
 * depending on the  frameSize (30 or 60 ms).
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *        - encoded           : encoded ISAC frame(s)
 *        - len               : bytes in encoded vector
 *
 * Output:
 *        - decoded           : The decoded vector
 *
 * Return value               : >0 - number of samples in decoded vector
 *                              -1 - Error
 */

WebRtc_Word16 WebRtcIsac_Decode(
			       ISACStruct*         ISAC_main_inst,
			       const WebRtc_UWord16* encoded,
			       WebRtc_Word16         lenEncodedBytes,
			       WebRtc_Word16*        decoded,
			       WebRtc_Word16*        speechType)
{
  WebRtc_Word16 isRCUPayload = 0;
  return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded,
		speechType, isRCUPayload);
}

/****************************************************************************
 * WebRtcIsac_DecodeRcu(...)
 *
 * This function decodes a redundant (RCU) iSAC frame. Function is called in
 * NetEq with a stored RCU payload i case of packet loss. Output speech length
 * will be a multiple of 480 samples: 480 or 960 samples,
 * depending on the framesize (30 or 60 ms).
 *
 * Input:
 *      - ISAC_main_inst     : ISAC instance.
 *      - encoded            : encoded ISAC RCU frame(s)
 *      - len                : bytes in encoded vector
 *
 * Output:
 *      - decoded            : The decoded vector
 *
 * Return value              : >0 - number of samples in decoded vector
 *                             -1 - Error
 */



WebRtc_Word16 WebRtcIsac_DecodeRcu(
				  ISACStruct*         ISAC_main_inst,
				  const WebRtc_UWord16* encoded,
				  WebRtc_Word16         lenEncodedBytes,
				  WebRtc_Word16*        decoded,
				  WebRtc_Word16*        speechType)
{
  WebRtc_Word16 isRCUPayload = 1;
  return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded,
		speechType, isRCUPayload);
}


/****************************************************************************
 * WebRtcIsac_DecodePlc(...)
 *
 * This function conducts PLC for ISAC frame(s). Output speech length
 * will be a multiple of 480 samples: 480 or 960 samples,
 * depending on the  frameSize (30 or 60 ms).
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *        - noOfLostFrames    : Number of PLC frames to produce
 *
 * Output:
 *        - decoded           : The decoded vector
 *
 * Return value               : >0 - number of samples in decoded PLC vector
 *                              -1 - Error
 */
WebRtc_Word16 WebRtcIsac_DecodePlc(
				  ISACStruct*         ISAC_main_inst,
				  WebRtc_Word16*        decoded,
				  WebRtc_Word16         noOfLostFrames)
{
  WebRtc_Word16 numSamples;
  ISACMainStruct* instISAC;


  /* typecast pointer to real structure */
  instISAC = (ISACMainStruct*)ISAC_main_inst;

  /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
  if(noOfLostFrames > 2)
    {
      noOfLostFrames = 2;
    }

  /* Get the number of samples per frame */
  switch(instISAC->decoderSamplingRateKHz)
    {
    case kIsacWideband:
      {
        numSamples = 480 * noOfLostFrames;
        break;
      }
    case kIsacSuperWideband:
      {
        numSamples = 960 * noOfLostFrames;
        break;
      }
    default:
      return -1;
    }

  /* Set output samples to zero */
  memset(decoded, 0, numSamples * sizeof(WebRtc_Word16));
  return numSamples;
}


/****************************************************************************
 * ControlLb(...) - Internal function for controling Lower Band
 * ControlUb(...) - Internal function for controling Upper Band
 * WebRtcIsac_Control(...) - API function
 *
 * This function sets the limit on the short-term average bit rate and the
 * frame length. Should be used only in Instantaneous mode.
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *        - rate              : limit on the short-term average bit rate,
 *                              in bits/second (between 10000 and 32000)
 *        -  frameSize         : number of milliseconds per frame (30 or 60)
 *
 * Return value               : 0  - ok
 *                             -1 - Error
 */
static WebRtc_Word16 ControlLb(
					  ISACLBStruct* instISAC,
					  double        rate,
					  WebRtc_Word16   frameSize)
{
  if((rate >= 10000) && (rate <= 32000))
    {
      instISAC->ISACencLB_obj.bottleneck = rate;
    }
  else
    {
      return -ISAC_DISALLOWED_BOTTLENECK;
    }

  if((frameSize == 30) ||  (frameSize == 60))
    {
      instISAC->ISACencLB_obj.new_framelength = (FS/1000) *  frameSize;
    }
  else
    {
      return -ISAC_DISALLOWED_FRAME_LENGTH;
    }

  return 0;
}

static WebRtc_Word16 ControlUb(
					  ISACUBStruct* instISAC,
					  double        rate)
{
  if((rate >= 10000) && (rate <= 32000))
    {
      instISAC->ISACencUB_obj.bottleneck = rate;
    }
  else
    {
      return -ISAC_DISALLOWED_BOTTLENECK;
    }
  return 0;
}

WebRtc_Word16 WebRtcIsac_Control(
				ISACStruct* ISAC_main_inst,
				WebRtc_Word32 bottleneckBPS,
				WebRtc_Word16 frameSize)
{
  ISACMainStruct *instISAC;
  WebRtc_Word16 status;
  double rateLB;
  double rateUB;
  enum ISACBandwidth bandwidthKHz;


  /* Typecast pointer to real structure */
  instISAC = (ISACMainStruct*)ISAC_main_inst;

  if(instISAC->codingMode == 0)
    {
      /* in adaptive mode */
      instISAC->errorCode = ISAC_MODE_MISMATCH;
      return -1;
    }

  /* check if encoder initiated */
  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
      return -1;
    }

  if(instISAC->encoderSamplingRateKHz == kIsacWideband)
    {
      // if the sampling rate is 16kHz then bandwith should be 8kHz,
      // regardless of bottleneck.
      bandwidthKHz = isac8kHz;
      rateLB = (bottleneckBPS > 32000)? 32000:bottleneckBPS;
      rateUB = 0;
    }
  else
    {
      if(WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB,
				   &bandwidthKHz) < 0)
	{
	  return -1;
	}
    }

  if((instISAC->encoderSamplingRateKHz == kIsacSuperWideband) &&
     (frameSize != 30)                                      &&
     (bandwidthKHz != isac8kHz))
    {
      // Cannot have 60 ms in super-wideband
      instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH;
      return -1;
    }

  status = ControlLb(&instISAC->instLB, rateLB, frameSize);
  if(status < 0)
    {
      instISAC->errorCode = -status;
      return -1;
    }
  if(bandwidthKHz != isac8kHz)
    {
      status = ControlUb(&(instISAC->instUB), rateUB);
      if(status < 0)
	{
	  instISAC->errorCode = -status;
	  return -1;
	}
    }

  //
  // Check if bandwidth is changing from wideband to super-wideband
  // then we have to synch data buffer of lower & upper-band. also
  // clean up the upper-band data buffer.
  //
  if((instISAC->bandwidthKHz == isac8kHz) &&
     (bandwidthKHz != isac8kHz))
    {
      memset(instISAC->instUB.ISACencUB_obj.data_buffer_float, 0,
	     sizeof(float) * (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES));

      if(bandwidthKHz == isac12kHz)
	{
	  instISAC->instUB.ISACencUB_obj.buffer_index =
	    instISAC->instLB.ISACencLB_obj.buffer_index;
	}
      else
	{
	  instISAC->instUB.ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES +
	    instISAC->instLB.ISACencLB_obj.buffer_index;

	  memcpy(&(instISAC->instUB.ISACencUB_obj.lastLPCVec),
            WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER);
	}
    }

  // update the payload limit it the bandwidth is changing.
  if(instISAC->bandwidthKHz != bandwidthKHz)
    {
      instISAC->bandwidthKHz = bandwidthKHz;
      UpdatePayloadSizeLimit(instISAC);
    }
  instISAC->bottleneck = bottleneckBPS;
  return 0;
}


/****************************************************************************
 * WebRtcIsac_ControlBwe(...)
 *
 * This function sets the initial values of bottleneck and frame-size if
 * iSAC is used in channel-adaptive mode. Through this API, users can
 * enforce a frame-size for all values of bottleneck. Then iSAC will not
 * automatically change the frame-size.
 *
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance.
 *        - rateBPS           : initial value of bottleneck in bits/second
 *                              10000 <= rateBPS <= 32000 is accepted
 *                              For default bottleneck set rateBPS = 0
 *        - frameSizeMs       : number of milliseconds per frame (30 or 60)
 *        - enforceFrameSize  : 1 to enforce the given frame-size through out
 *                              the adaptation process, 0 to let iSAC change
 *                              the frame-size if required.
 *
 * Return value               : 0  - ok
 *                             -1 - Error
 */
WebRtc_Word16 WebRtcIsac_ControlBwe(
				   ISACStruct* ISAC_main_inst,
				   WebRtc_Word32 bottleneckBPS,
				   WebRtc_Word16 frameSizeMs,
				   WebRtc_Word16 enforceFrameSize)
{
  ISACMainStruct *instISAC;
  enum ISACBandwidth bandwidth;

  /* Typecast pointer to real structure */
  instISAC = (ISACMainStruct *)ISAC_main_inst;

  /* check if encoder initiated */
  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
      return -1;
    }

  /* Check that we are in channel-adaptive mode, otherwise, return (-1) */
  if(instISAC->codingMode != 0)
    {
      instISAC->errorCode = ISAC_MODE_MISMATCH;
      return -1;
    }
  if((frameSizeMs != 30) &&
     (instISAC->encoderSamplingRateKHz == kIsacSuperWideband))
    {
      return -1;
    }

  /* Set struct variable if enforceFrameSize is set. ISAC will then */
  /* keep the chosen frame size. */
  if((enforceFrameSize != 0) /*||
                               (instISAC->samplingRateKHz == kIsacSuperWideband)*/)
    {
      instISAC->instLB.ISACencLB_obj.enforceFrameSize = 1;
    }
  else
    {
      instISAC->instLB.ISACencLB_obj.enforceFrameSize = 0;
    }

  /* Set initial rate, if value between 10000 and 32000,                */
  /* if rateBPS is 0, keep the default initial bottleneck value (15000) */
  if(bottleneckBPS != 0)
    {
      double rateLB;
      double rateUB;
      if(WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, &bandwidth) < 0)
	{
	  return -1;
	}
      instISAC->bwestimator_obj.send_bw_avg = (float)bottleneckBPS;
      instISAC->bandwidthKHz = bandwidth;
    }

  /* Set initial  frameSize. If enforceFrameSize is set the frame size will
     not change */
  if(frameSizeMs != 0)
    {
      if((frameSizeMs  == 30) || (frameSizeMs == 60))
	{
	  instISAC->instLB.ISACencLB_obj.new_framelength = (FS/1000) *
	    frameSizeMs;
	  //instISAC->bwestimator_obj.rec_header_rate = ((float)HEADER_SIZE *
	  //    8.0f * 1000.0f / (float)frameSizeMs);
	}
      else
	{
	  instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH;
	  return -1;
	}
    }
  return 0;
}


/****************************************************************************
 * WebRtcIsac_GetDownLinkBwIndex(...)
 *
 * This function returns index representing the Bandwidth estimate from
 * other side to this side.
 *
 * Input:
 *        - ISAC_main_inst    : iSAC struct
 *
 * Output:
 *        - bweIndex         : Bandwidth estimate to transmit to other side.
 *
 */
WebRtc_Word16 WebRtcIsac_GetDownLinkBwIndex(
				   ISACStruct*  ISAC_main_inst,
				   WebRtc_Word16* bweIndex,
				   WebRtc_Word16* jitterInfo)
{
  ISACMainStruct *instISAC;

  /* typecast pointer to real structure */
  instISAC = (ISACMainStruct*)ISAC_main_inst;

  /* check if encoder initiated */
  if((instISAC->initFlag & BIT_MASK_DEC_INIT) !=
     BIT_MASK_DEC_INIT)
    {
      instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
      return -1;
    }

  /* Call function to get Bandwidth Estimate */
  WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj),
                                   bweIndex, jitterInfo, instISAC->decoderSamplingRateKHz);
  return 0;
}


/****************************************************************************
 * WebRtcIsac_UpdateUplinkBw(...)
 *
 * This function takes an index representing the Bandwidth estimate from
 * this side to other side and updates BWE.
 *
 * Input:
 *        - ISAC_main_inst    : iSAC struct
 *        - rateIndex         : Bandwidth estimate from other side.
 *
 * Return value               : 0 - ok
 *                             -1 - index out of range
 */
WebRtc_Word16 WebRtcIsac_UpdateUplinkBw(
			       ISACStruct*   ISAC_main_inst,
			       WebRtc_Word16   bweIndex)
{
  ISACMainStruct *instISAC;
  WebRtc_Word16 returnVal;

  /* typecast pointer to real structure */
  instISAC = (ISACMainStruct *)ISAC_main_inst;

  /* check if encoder initiated */
  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
      return -1;
    }

  /* Call function to get Bandwidth Estimate */
  returnVal = WebRtcIsac_UpdateUplinkBwImpl(
					&(instISAC->bwestimator_obj), bweIndex,
					instISAC->encoderSamplingRateKHz);

  if(returnVal < 0)
    {
      instISAC->errorCode = -returnVal;
      return -1;
    }
  else
    {
      return 0;
    }
}


/****************************************************************************
 * WebRtcIsac_ReadBwIndex(...)
 *
 * This function returns the index of the Bandwidth estimate from the
 * bitstream.
 *
 * Input:
 *        - encoded           : Encoded bitstream
 *
 * Output:
 *        - frameLength       : Length of frame in packet (in samples)
 *        - bweIndex         : Bandwidth estimate in bitstream
 *
 */
WebRtc_Word16 WebRtcIsac_ReadBwIndex(
			       const WebRtc_Word16* encoded,
			       WebRtc_Word16*       bweIndex)
{
  Bitstr streamdata;
#ifndef WEBRTC_BIG_ENDIAN
  int k;
#endif
  WebRtc_Word16 err;

  streamdata.W_upper = 0xFFFFFFFF;
  streamdata.streamval = 0;
  streamdata.stream_index = 0;

#ifndef WEBRTC_BIG_ENDIAN
  for(k = 0; k < 10; k++)
    {
      streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >>
					       ((k&1) << 3)) & 0xFF);
    }
#else
  memcpy(streamdata.stream, encoded, 10);
#endif

  /* decode frame length */
  err = WebRtcIsac_DecodeFrameLen(&streamdata, bweIndex);
  if(err < 0)
    {
      return err;
    }

  /* decode BW estimation */
  err = WebRtcIsac_DecodeSendBW(&streamdata, bweIndex);
  if(err < 0)
    {
      return err;
    }

  return 0;
}


/****************************************************************************
 * WebRtcIsac_ReadFrameLen(...)
 *
 * This function returns the length of the frame represented in the packet.
 *
 * Input:
 *        - encoded           : Encoded bitstream
 *
 * Output:
 *        - frameLength       : Length of frame in packet (in samples)
 *
 */
WebRtc_Word16 WebRtcIsac_ReadFrameLen(
				    ISACStruct*        ISAC_main_inst,
				    const WebRtc_Word16* encoded,
				    WebRtc_Word16*       frameLength)
{
  Bitstr streamdata;
#ifndef WEBRTC_BIG_ENDIAN
  int k;
#endif
  WebRtc_Word16 err;
  ISACMainStruct* instISAC;

  streamdata.W_upper = 0xFFFFFFFF;
  streamdata.streamval = 0;
  streamdata.stream_index = 0;

#ifndef WEBRTC_BIG_ENDIAN
  for (k=0; k<10; k++) {
    streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >>
                                             ((k&1) << 3)) & 0xFF);
  }
#else
  memcpy(streamdata.stream, encoded, 10);
#endif

  /* decode frame length */
  err = WebRtcIsac_DecodeFrameLen(&streamdata, frameLength);
  if(err < 0) {
    return -1;
  }
  instISAC = (ISACMainStruct*)ISAC_main_inst;

  if(instISAC->decoderSamplingRateKHz == kIsacSuperWideband)
    {
      // the decoded frame length indicates the number of samples in
      // lower-band in this case, multiply by 2 to get the total number
      // of samples.
      *frameLength <<= 1;
    }

  return 0;
}


/*******************************************************************************
 * WebRtcIsac_GetNewFrameLen(...)
 *
 * returns the frame lenght (in samples) of the next packet. In the case of
 * channel-adaptive mode, iSAC decides on its frame lenght based on the
 * estimated bottleneck this allows a user to prepare for the next packet
 * (at the encoder).
 *
 * The primary usage is in CE to make the iSAC works in channel-adaptive mode
 *
 * Input:
 *        - ISAC_main_inst     : iSAC struct
 *
 * Return Value                : frame lenght in samples
 *
 */
WebRtc_Word16 WebRtcIsac_GetNewFrameLen(
				       ISACStruct *ISAC_main_inst)
{
  ISACMainStruct *instISAC;

  /* typecast pointer to real structure */
  instISAC = (ISACMainStruct *)ISAC_main_inst;

  /* Return new frame length */
  if(instISAC->encoderSamplingRateKHz == kIsacWideband)
    {
      return (instISAC->instLB.ISACencLB_obj.new_framelength);
    }
  else
    {
      return ((instISAC->instLB.ISACencLB_obj.new_framelength) << 1);
    }
}


/****************************************************************************
 * WebRtcIsac_GetErrorCode(...)
 *
 * This function can be used to check the error code of an iSAC instance.
 * When a function returns -1 a error code will be set for that instance.
 * The function below extract the code of the last error that occured in
 * the specified instance.
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance
 *
 * Return value               : Error code
 */
WebRtc_Word16 WebRtcIsac_GetErrorCode(
				     ISACStruct *ISAC_main_inst)
{
  ISACMainStruct *instISAC;
  /* typecast pointer to real structure */
  instISAC = (ISACMainStruct *)ISAC_main_inst;

  return (instISAC->errorCode);
}


/****************************************************************************
 * WebRtcIsac_GetUplinkBw(...)
 *
 * This function outputs the target bottleneck of the codec. In
 * channel-adaptive mode, the target bottleneck is specified through in-band
 * signalling retreived by bandwidth estimator.
 * In channel-independent, also called instantaneous mode, the target
 * bottleneck is provided to the encoder by calling xxx_control(...) (if
 * xxx_control is never called the default values is).
 * Note that the output is the iSAC internal operating bottleneck whch might
 * differ slightly from the one provided through xxx_control().
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *
 * Output:
 *        - *bottleneck       : bottleneck in bits/sec
 *
 * Return value               : -1 if error happens
 *                               0 bit-rates computed correctly.
 */
WebRtc_Word16 WebRtcIsac_GetUplinkBw(
				       ISACStruct*  ISAC_main_inst,
				       WebRtc_Word32* bottleneck)
{
  ISACMainStruct* instISAC = (ISACMainStruct *)ISAC_main_inst;

  if(instISAC->codingMode == 0)
    {
      // we are in adaptive mode then get the bottleneck from BWE
      *bottleneck = (WebRtc_Word32)instISAC->bwestimator_obj.send_bw_avg;
    }
  else
    {
      *bottleneck = instISAC->bottleneck;
    }

  if((*bottleneck > 32000) && (*bottleneck < 38000))
    {
      *bottleneck = 32000;
    }
  else if((*bottleneck > 45000) && (*bottleneck < 50000))
    {
      *bottleneck = 45000;
    }
  else if(*bottleneck > 56000)
    {
      *bottleneck = 56000;
    }

  return 0;
}


/******************************************************************************
 * WebRtcIsac_SetMaxPayloadSize(...)
 *
 * This function sets a limit for the maximum payload size of iSAC. The same
 * value is used both for 30 and 60 ms packets. If the encoder sampling rate
 * is 16 kHz the maximum payload size is between 120 and 400 bytes. If the
 * encoder sampling rate is 32 kHz the maximum payload size is between 120
 * and 600 bytes.
 *
 * ---------------
 * IMPORTANT NOTES
 * ---------------
 * The size of a packet is limited to the minimum of 'max-payload-size' and
 * 'max-rate.' For instance, let's assume the max-payload-size is set to
 * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps
 * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms
 * frame-size. Then a packet with a frame-size of 30 ms is limited to 150,
 * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to
 * 170 bytes, i.e. min(170, 300).
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *        - maxPayloadBytes   : maximum size of the payload in bytes
 *                              valid values are between 100 and 400 bytes
 *                              if encoder sampling rate is 16 kHz. For
 *                              32 kHz encoder sampling rate valid values
 *                              are between 100 and 600 bytes.
 *
 * Return value               : 0 if successful
 *                             -1 if error happens
 */
WebRtc_Word16 WebRtcIsac_SetMaxPayloadSize(
					  ISACStruct* ISAC_main_inst,
					  WebRtc_Word16 maxPayloadBytes)
{
  ISACMainStruct *instISAC;
  WebRtc_Word16 status = 0;

  /* typecast pointer to real structure  */
  instISAC = (ISACMainStruct *)ISAC_main_inst;

  /* check if encoder initiated */
  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
      return -1;
    }

  if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband)
    {
      // sanity check
      if(maxPayloadBytes < 120)
	{
	  // maxRate is out of valid range
	  // set to the acceptable value and return -1.
	  maxPayloadBytes = 120;
	  status = -1;
	}

      /* sanity check */
      if(maxPayloadBytes > STREAM_SIZE_MAX)
	{
	  // maxRate is out of valid range
	  // set to the acceptable value and return -1.
	  maxPayloadBytes = STREAM_SIZE_MAX;
	  status = -1;
	}
    }
  else
    {
      if(maxPayloadBytes < 120)
	{
	  // max payload-size is out of valid range
	  // set to the acceptable value and return -1.
	  maxPayloadBytes = 120;
	  status = -1;
	}
      if(maxPayloadBytes > STREAM_SIZE_MAX_60)
	{
	  // max payload-size is out of valid range
	  // set to the acceptable value and return -1.
	  maxPayloadBytes = STREAM_SIZE_MAX_60;
	  status = -1;
	}
    }
  instISAC->maxPayloadSizeBytes = maxPayloadBytes;
  UpdatePayloadSizeLimit(instISAC);
  return status;
}


/******************************************************************************
 * WebRtcIsac_SetMaxRate(...)
 *
 * This function sets the maximum rate which the codec may not exceed for
 * any signal packet. The maximum rate is defined and payload-size per
 * frame-size in bits per second.
 *
 * The codec has a maximum rate of 53400 bits per second (200 bytes per 30
 * ms) if the encoder sampling rate is 16kHz, and 160 kbps (600 bytes/30 ms)
 * if the encoder sampling rate is 32 kHz.
 *
 * It is possible to set a maximum rate between 32000 and 53400 bits/sec
 * in wideband mode, and 32000 to 160000 bits/sec in super-wideband mode.
 *
 * ---------------
 * IMPORTANT NOTES
 * ---------------
 * The size of a packet is limited to the minimum of 'max-payload-size' and
 * 'max-rate.' For instance, let's assume the max-payload-size is set to
 * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps
 * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms
 * frame-size. Then a packet with a frame-size of 30 ms is limited to 150,
 * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to
 * 170 bytes, min(170, 300).
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *        - maxRate           : maximum rate in bits per second,
 *                              valid values are 32000 to 53400 bits/sec in
 *                              wideband mode, and 32000 to 160000 bits/sec in
 *                              super-wideband mode.
 *
 * Return value               : 0 if successful
 *                             -1 if error happens
 */
WebRtc_Word16 WebRtcIsac_SetMaxRate(
				   ISACStruct* ISAC_main_inst,
				   WebRtc_Word32 maxRate)
{
  ISACMainStruct *instISAC;
  WebRtc_Word16 maxRateInBytesPer30Ms;
  WebRtc_Word16 status = 0;

  /* typecast pointer to real structure */
  instISAC = (ISACMainStruct *)ISAC_main_inst;

  /* check if encoder initiated */
  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
      return -1;
    }
  /*
    Calculate maximum number of bytes per 30 msec packets for the
    given maximum rate. Multiply with 30/1000 to get number of
    bits per 30 ms, divide by 8 to get number of bytes per 30 ms:
    maxRateInBytes = floor((maxRate * 30/1000) / 8);
  */
  maxRateInBytesPer30Ms = (WebRtc_Word16)(maxRate*3/800);

  if(instISAC->encoderSamplingRateKHz == kIsacWideband)
    {
      if(maxRate < 32000)
	{
	  // max rate is out of valid range
	  // set to the acceptable value and return -1.
	  maxRateInBytesPer30Ms = 120;
	  status = -1;
	}

      if(maxRate > 53400)
	{
	  // max rate is out of valid range
	  // set to the acceptable value and return -1.
	  maxRateInBytesPer30Ms = 200;
	  status = -1;
	}
    }
  else
    {
      if(maxRateInBytesPer30Ms < 120)
	{
	  // maxRate is out of valid range
	  // set to the acceptable value and return -1.
	  maxRateInBytesPer30Ms = 120;
	  status = -1;
	}

      if(maxRateInBytesPer30Ms > STREAM_SIZE_MAX)
	{
	  // maxRate is out of valid range
	  // set to the acceptable value and return -1.
	  maxRateInBytesPer30Ms = STREAM_SIZE_MAX;
	  status = -1;
	}
    }
  instISAC->maxRateBytesPer30Ms = maxRateInBytesPer30Ms;
  UpdatePayloadSizeLimit(instISAC);
  return status;
}


/****************************************************************************
 * WebRtcIsac_GetRedPayload(...)
 *
 * Populates "encoded" with the redundant payload of the recently encoded
 * frame. This function has to be called once that WebRtcIsac_Encode(...)
 * returns a positive value. Regardless of the frame-size this function will
 * be called only once after encoding is completed. The bit-stream is
 * targeted for 16000 bit/sec.
 *
 * Input:
 *        - ISAC_main_inst    : iSAC struct
 *
 * Output:
 *        - encoded           : the encoded data vector
 *
 *
 * Return value               : >0 - Length (in bytes) of coded data
 *                            : -1 - Error
 *
 *
 */
WebRtc_Word16 WebRtcIsac_GetRedPayload(
				      ISACStruct*  ISAC_main_inst,
				      WebRtc_Word16* encoded)
{
  ISACMainStruct* instISAC;
  Bitstr          iSACBitStreamInst;
  WebRtc_Word16     streamLenLB;
  WebRtc_Word16     streamLenUB;
  WebRtc_Word16     streamLen;
  WebRtc_Word16     totalLenUB;
  WebRtc_UWord8*    ptrEncodedUW8 = (WebRtc_UWord8*)encoded;
#ifndef WEBRTC_BIG_ENDIAN
  int k;
#endif

  /* typecast pointer to real structure */
  instISAC = (ISACMainStruct*)ISAC_main_inst;


  if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     BIT_MASK_ENC_INIT)
    {
      instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
    }


  iSACBitStreamInst.W_upper = 0xFFFFFFFF;
  iSACBitStreamInst.streamval = 0;
  iSACBitStreamInst.stream_index = 0;


  streamLenLB = WebRtcIsac_EncodeStoredDataLb(
					      &instISAC->instLB.ISACencLB_obj.SaveEnc_obj,
					      &iSACBitStreamInst,
					      instISAC->instLB.ISACencLB_obj.lastBWIdx,
					      RCU_TRANSCODING_SCALE);

  if(streamLenLB < 0)
    {
      return -1;
    }

  /* convert from bytes to WebRtc_Word16 */
  memcpy(ptrEncodedUW8, iSACBitStreamInst.stream, streamLenLB);

  streamLen = streamLenLB;

  if(instISAC->bandwidthKHz == isac8kHz)
    {
      return streamLenLB;
    }

  streamLenUB = WebRtcIsac_GetRedPayloadUb(
					   &instISAC->instUB.ISACencUB_obj.SaveEnc_obj,
					   &iSACBitStreamInst, instISAC->bandwidthKHz);

  if(streamLenUB < 0)
    {
      // an error has happened but this is not the error due to a
      // bit-stream larger than the limit
      return -1;
    }

  // We have one byte to write the total length of the upper band
  // the length include the bitstream length, check-sum and the
  // single byte where the length is written to. This is according to
  // iSAC wideband and how the "garbage" is dealt.
  totalLenUB = streamLenUB + 1 + LEN_CHECK_SUM_WORD8;
  if(totalLenUB > 255)
    {
      streamLenUB = 0;
    }

  // Generate CRC if required.
  if((instISAC->bandwidthKHz != isac8kHz) &&
     (streamLenUB > 0))
    {
      WebRtc_UWord32 crc;
      streamLen += totalLenUB;
      ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)totalLenUB;
      memcpy(&ptrEncodedUW8[streamLenLB+1], iSACBitStreamInst.stream, streamLenUB);

      WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])),
			streamLenUB, &crc);
#ifndef WEBRTC_BIG_ENDIAN
      for(k = 0; k < LEN_CHECK_SUM_WORD8; k++)
	{
	  ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] =
	    (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF);
	}
#else
      memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc,
	     LEN_CHECK_SUM_WORD8);
#endif
    }


  return streamLen;
}


/****************************************************************************
 * WebRtcIsac_version(...)
 *
 * This function returns the version number.
 *
 * Output:
 *        - version      : Pointer to character string
 *
 */
void WebRtcIsac_version(char *version)
{
  strcpy(version, "4.3.0");
}


/******************************************************************************
 * WebRtcIsac_SetEncSampRate()
 * Set the sampling rate of the encoder. Initialization of the encoder WILL
 * NOT overwrite the sampling rate of the encoder. The default value is 16 kHz
 * which is set when the instance is created. The encoding-mode and the
 * bottleneck remain unchanged by this call, however, the maximum rate and
 * maximum payload-size will reset to their default value.
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *        - sampRate          : enumerator specifying the sampling rate.
 *
 * Return value               : 0 if successful
 *                             -1 if failed.
 */
WebRtc_Word16 WebRtcIsac_SetEncSampRate(
				       ISACStruct*               ISAC_main_inst,
				       enum IsacSamplingRate sampRate)
{
  ISACMainStruct* instISAC;

  instISAC = (ISACMainStruct*)ISAC_main_inst;

  if((sampRate != kIsacWideband) &&
     (sampRate != kIsacSuperWideband))
    {
      // Sampling Frequency is not supported
      instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY;
      return -1;
    }
  else if((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
          BIT_MASK_ENC_INIT)
    {
      if(sampRate == kIsacWideband)
      {
        instISAC->bandwidthKHz = isac8kHz;
      }
      else
      {
        instISAC->bandwidthKHz = isac16kHz;
      }
      instISAC->encoderSamplingRateKHz = sampRate;
      return 0;
    }
  else
    {
      ISACUBStruct* instUB = &(instISAC->instUB);
      ISACLBStruct* instLB = &(instISAC->instLB);
      double bottleneckLB;
      double bottleneckUB;
      WebRtc_Word32 bottleneck = instISAC->bottleneck;
      WebRtc_Word16 codingMode = instISAC->codingMode;
      WebRtc_Word16 frameSizeMs = instLB->ISACencLB_obj.new_framelength / (FS / 1000);

      if((sampRate == kIsacWideband) &&
	 (instISAC->encoderSamplingRateKHz == kIsacSuperWideband))
	{
	  // changing from super-wideband to wideband.
	  // we don't need to re-initialize the encoder of the
	  // lower-band.
	  instISAC->bandwidthKHz = isac8kHz;
	  if(codingMode == 1)
	    {
	      ControlLb(instLB,
				   (bottleneck > 32000)? 32000:bottleneck, FRAMESIZE);
	    }
	  instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60;
	  instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30;
	}
      else if((sampRate == kIsacSuperWideband) &&
	      (instISAC->encoderSamplingRateKHz == kIsacWideband))
	{
	  if(codingMode == 1)
	    {
	      WebRtcIsac_RateAllocation(bottleneck, &bottleneckLB, &bottleneckUB,
					&(instISAC->bandwidthKHz));
	    }

          instISAC->bandwidthKHz = isac16kHz;
	  instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX;
	  instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX;

	  EncoderInitLb(instLB, codingMode, sampRate);
	  EncoderInitUb(instUB, instISAC->bandwidthKHz);

	  memset(instISAC->analysisFBState1, 0,
		 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32));
	  memset(instISAC->analysisFBState2, 0,
		 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32));

	  if(codingMode == 1)
	    {
	      instISAC->bottleneck = bottleneck;
	      ControlLb(instLB, bottleneckLB,
				   (instISAC->bandwidthKHz == isac8kHz)? frameSizeMs:FRAMESIZE);
	      if(instISAC->bandwidthKHz > isac8kHz)
		{
		  ControlUb(instUB, bottleneckUB);
		}
	    }
	  else
	    {
	      instLB->ISACencLB_obj.enforceFrameSize = 0;
	      instLB->ISACencLB_obj.new_framelength = FRAMESAMPLES;
	    }
	}
      instISAC->encoderSamplingRateKHz = sampRate;
      return 0;
    }
}


/******************************************************************************
 * WebRtcIsac_SetDecSampRate()
 * Set the sampling rate of the decoder.  Initialization of the decoder WILL
 * NOT overwrite the sampling rate of the encoder. The default value is 16 kHz
 * which is set when the instance is created.
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *        - sampRate          : enumerator specifying the sampling rate.
 *
 * Return value               : 0 if successful
 *                             -1 if failed.
 */
WebRtc_Word16 WebRtcIsac_SetDecSampRate(
				       ISACStruct*               ISAC_main_inst,
				       enum IsacSamplingRate sampRate)
{
  ISACMainStruct* instISAC;

  instISAC = (ISACMainStruct*)ISAC_main_inst;

  if((sampRate != kIsacWideband) &&
     (sampRate != kIsacSuperWideband))
    {
      // Sampling Frequency is not supported
      instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY;
      return -1;
    }
  else
    {
      if((instISAC->decoderSamplingRateKHz == kIsacWideband) &&
	 (sampRate == kIsacSuperWideband))
	{
	  // switching from wideband to super-wideband at the decoder
	  // we need to reset the filter-bank and initialize
	  // upper-band decoder.
	  memset(instISAC->synthesisFBState1, 0,
		 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32));
	  memset(instISAC->synthesisFBState2, 0,
		 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32));

	  if(DecoderInitUb(&(instISAC->instUB)) < 0)
	    {
	      return -1;
	    }
	}
      instISAC->decoderSamplingRateKHz = sampRate;
      return 0;
    }
}


/******************************************************************************
 * WebRtcIsac_EncSampRate()
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *
 * Return value               : enumerator representing sampling frequency
 *                              associated with the encoder, the input audio
 *                              is expected to be sampled at this rate.
 *
 */
enum IsacSamplingRate WebRtcIsac_EncSampRate(
					       ISACStruct*                ISAC_main_inst)
{
  ISACMainStruct* instISAC;

  instISAC = (ISACMainStruct*)ISAC_main_inst;

  return instISAC->encoderSamplingRateKHz;
}


/******************************************************************************
 * WebRtcIsac_DecSampRate()
 * Return the sampling rate of the decoded audio.
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *
 * Return value               : enumerator representing sampling frequency
 *                              associated with the decoder, i.e. the
 *                              sampling rate of the decoded audio.
 *
 */
enum IsacSamplingRate WebRtcIsac_DecSampRate(
					       ISACStruct*                ISAC_main_inst)
{
  ISACMainStruct* instISAC;

  instISAC = (ISACMainStruct*)ISAC_main_inst;

  return instISAC->decoderSamplingRateKHz;
}
