/*
 *  Copyright (c) 2012 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 "webrtc/modules/audio_coding/codecs/isac/main/include/isac.h"

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

#include "webrtc/rtc_base/checks.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/source/bandwidth_estimator.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/source/codec.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/source/crc.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/source/os_specific_inline.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/source/structs.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 translates 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) {
  int16_t lim30MsPayloadBytes = WEBRTC_SPL_MIN(
                          (instISAC->maxPayloadSizeBytes),
                          (instISAC->maxRateBytesPer30Ms));
  int16_t 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 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)) {
    int32_t bottleneck =
        WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj);

    /* 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 choice we have here. */
      instISAC->instLB.ISACencLB_obj.bottleneck =
        (bottleneck > 32000) ? 32000 : bottleneck;
      instISAC->bandwidthKHz = isac8kHz;
    } else {
      /* Do the rate-allocation 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
         * care of buffer_index and the last LPC vector. */
      }
    }
  }
}


/****************************************************************************
 * GetSendBandwidthInfo(...)
 *
 * This is called to get the bandwidth info. This info is the bandwidth and
 * the jitter of 'there-to-here' channel, estimated 'here.' These info
 * is signaled in an in-band fashion to the other side.
 *
 * The call to the bandwidth estimator triggers 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
 * generate 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,
                                 int16_t* bandwidthIndex,
                                 int16_t* 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
 */
int16_t WebRtcIsac_AssignSize(int* sizeInBytes) {
  *sizeInBytes = sizeof(ISACMainStruct) * 2 / sizeof(int16_t);
  return 0;
}


/****************************************************************************
 * WebRtcIsac_Assign(...)
 *
 * This function assigns the memory already created to the ISAC instance.
 *
 * Input:
 *        - ISAC_main_inst    : address of the pointer to the coder instance.
 *        - instISAC_Addr     : the already allocated memory, where we put the
 *                              iSAC structure.
 *
 * Return value               : 0 - Ok
 *                             -1 - Error
 */
int16_t 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;
    instISAC->in_sample_rate_hz = 16000;

    WebRtcIsac_InitTransform(&instISAC->transform_tables);
    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
 */
int16_t WebRtcIsac_Create(ISACStruct** ISAC_main_inst) {
  ISACMainStruct* instISAC;

  if (ISAC_main_inst != NULL) {
    instISAC = (ISACMainStruct*)malloc(sizeof(ISACMainStruct));
    *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;
      instISAC->in_sample_rate_hz = 16000;

      WebRtcIsac_InitTransform(&instISAC->transform_tables);
      return 0;
    } else {
      return -1;
    }
  } 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
 */
int16_t WebRtcIsac_Free(ISACStruct* ISAC_main_inst) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  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 int16_t EncoderInitLb(ISACLBStruct* instLB,
                             int16_t codingMode,
                             enum IsacSamplingRate sampRate) {
  int16_t 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
     * instantaneous 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 int16_t EncoderInitUb(ISACUBStruct* instUB,
                             int16_t bandwidth) {
  int16_t 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;
}


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

  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(int32_t));
    memset(instISAC->analysisFBState2, 0,
           FB_STATE_SIZE_WORD32 * sizeof(int32_t));

    status = EncoderInitUb(&(instISAC->instUB),
                           instISAC->bandwidthKHz);
    if (status < 0) {
      instISAC->errorCode = -status;
      return -1;
    }
  }
  /* Initialization 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
 */
int WebRtcIsac_Encode(ISACStruct* ISAC_main_inst,
                      const int16_t* speechIn,
                      uint8_t* encoded) {
  float inFrame[FRAMESAMPLES_10ms];
  int16_t speechInLB[FRAMESAMPLES_10ms];
  int16_t speechInUB[FRAMESAMPLES_10ms];
  int streamLenLB = 0;
  int streamLenUB = 0;
  int streamLen = 0;
  size_t k = 0;
  uint8_t garbageLen = 0;
  int32_t bottleneck = 0;
  int16_t bottleneckIdx = 0;
  int16_t jitterInfo = 0;

  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  ISACLBStruct* instLB = &(instISAC->instLB);
  ISACUBStruct* 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, SWBFRAMESAMPLES_10ms, 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(&instISAC->transform_tables,
                                    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 =
        (int16_t)(streamLenLB + 1 + LEN_CHECK_SUM_WORD8);
    /* Encode upper-band. */
    switch (instISAC->bandwidthKHz) {
      case isac12kHz: {
        streamLenUB = WebRtcIsac_EncodeUb12(&instISAC->transform_tables,
                                            inFrame, &instUB->ISACencUB_obj,
                                            jitterInfo);
        break;
      }
      case isac16kHz: {
        streamLenUB = WebRtcIsac_EncodeUb16(&instISAC->transform_tables,
                                            inFrame, &instUB->ISACencUB_obj,
                                            jitterInfo);
        break;
      }
      case isac8kHz: {
        streamLenUB = 0;
        break;
      }
    }

    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 byte 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(encoded, instLB->ISACencLB_obj.bitstr_obj.stream, streamLenLB);
    streamLen = streamLenLB;
    if (streamLenUB > 0) {
      encoded[streamLenLB] = (uint8_t)(streamLenUB + 1 + LEN_CHECK_SUM_WORD8);
      memcpy(&encoded[streamLenLB + 1],
             instUB->ISACencUB_obj.bitstr_obj.stream,
             streamLenUB);
      streamLen += encoded[streamLenLB];
    } else {
      encoded[streamLenLB] = 0;
    }
  } else {
    if (streamLenLB == 0) {
      return 0;
    }
    memcpy(encoded, instLB->ISACencLB_obj.bitstr_obj.stream, streamLenLB);
    streamLenUB = 0;
    streamLen = streamLenLB;
  }

  /* Add Garbage if required. */
  bottleneck = WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj);
  if (instISAC->codingMode == 0) {
    int minBytes;
    int limit;
    uint8_t* 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 = &encoded[streamLenLB];
      limit = streamLen + 255;
    } else {
      ptrGarbage = &encoded[streamLenLB + 1 + streamLenUB];
      limit = streamLen + (255 - encoded[streamLenLB]);
    }
    minBytes = (minBytes > limit) ? limit : minBytes;

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

    /* Save data for creation of multiple bit-streams. */
    /* If bit-stream too short then add garbage at the end. */
    if (garbageLen > 0) {
      /* Overwrite the garbage area to avoid leaking possibly sensitive data
         over the network. This also makes the output deterministic. */
      memset(ptrGarbage, 0, garbageLen);

      /* 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)) {
        encoded[streamLenLB] = garbageLen;
      } else {
        encoded[streamLenLB] += garbageLen;
        /* Write the length of the garbage at the end of the upper-band
         *  bit-stream, if exists. This helps for sanity check. */
        encoded[streamLenLB + 1 + streamLenUB] = 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)) {
    uint32_t crc;

    WebRtcIsac_GetCrc((int16_t*)(&(encoded[streamLenLB + 1])),
                      streamLenUB + garbageLen, &crc);
#ifndef WEBRTC_ARCH_BIG_ENDIAN
    for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) {
      encoded[streamLen - LEN_CHECK_SUM_WORD8 + k] =
          (uint8_t)(crc >> (24 - k * 8));
    }
#else
    memcpy(&encoded[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 2! 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.
 */
int16_t WebRtcIsac_GetNewBitStream(ISACStruct*  ISAC_main_inst,
                                   int16_t  bweIndex,
                                   int16_t  jitterInfo,
                                   int32_t  rate,
                                   uint8_t* encoded,
                                   int16_t  isRCU) {
  Bitstr iSACBitStreamInst;   /* Local struct for bitstream handling */
  int16_t streamLenLB;
  int16_t streamLenUB;
  int16_t totalStreamLen;
  double gain2;
  double gain1;
  float scale;
  enum ISACBandwidth bandwidthKHz;
  double rateLB;
  double rateUB;
  int32_t currentBN;
  uint32_t crc;
#ifndef WEBRTC_ARCH_BIG_ENDIAN
  int16_t  k;
#endif
  ISACMainStruct* 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;
  }

  /* A gain [dB] for the given rate. */
  gain1 = WebRtcIsac_GetSnr(
      rateLB, instISAC->instLB.ISACencLB_obj.current_framesamples);
  /* The gain [dB] 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 int16_t. */
  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;

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

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

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

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

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

  WebRtcIsac_GetCrc((int16_t*)(&(encoded[streamLenLB + 1])),
                    streamLenUB, &crc);
#ifndef WEBRTC_ARCH_BIG_ENDIAN
  for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) {
    encoded[totalStreamLen - LEN_CHECK_SUM_WORD8 + k] =
      (uint8_t)((crc >> (24 - k * 8)) & 0xFF);
  }
#else
  memcpy(&encoded[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.
 */
static void DecoderInitLb(ISACLBStruct* instISAC) {
  int i;
  /* Initialize 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);
}

static void 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);
}

void WebRtcIsac_DecoderInit(ISACStruct* ISAC_main_inst) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;

  DecoderInitLb(&instISAC->instLB);
  if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) {
    memset(instISAC->synthesisFBState1, 0,
           FB_STATE_SIZE_WORD32 * sizeof(int32_t));
    memset(instISAC->synthesisFBState2, 0,
           FB_STATE_SIZE_WORD32 * sizeof(int32_t));
    DecoderInitUb(&(instISAC->instUB));
  }
  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;
}


/****************************************************************************
 * WebRtcIsac_UpdateBwEstimate(...)
 *
 * This function updates the estimate of the bandwidth.
 *
 * NOTE:
 * The estimates of bandwidth is not valid if the sample rate of the far-end
 * encoder is set to 48 kHz and send timestamps are increamented according to
 * 48 kHz sampling rate.
 *
 * 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
 */
int16_t WebRtcIsac_UpdateBwEstimate(ISACStruct* ISAC_main_inst,
                                    const uint8_t* encoded,
                                    size_t packet_size,
                                    uint16_t rtp_seq_number,
                                    uint32_t send_ts,
                                    uint32_t arr_ts) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  Bitstr streamdata;
#ifndef WEBRTC_ARCH_BIG_ENDIAN
  int k;
#endif
  int16_t err;

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

  /* Check that the size of the packet is valid, and if not return without
   * updating the bandwidth estimate. A valid size is at least 10 bytes. */
  if (packet_size < 10) {
    /* Return error code if the packet length is null. */
    instISAC->errorCode = ISAC_EMPTY_PACKET;
    return -1;
  }

  WebRtcIsac_ResetBitstream(&(streamdata));

#ifndef WEBRTC_ARCH_BIG_ENDIAN
  for (k = 0; k < 10; k++) {
    uint16_t ek = ((const uint16_t*)encoded)[k >> 1];
    streamdata.stream[k] = (uint8_t)((ek >> ((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 int Decode(ISACStruct* ISAC_main_inst,
                  const uint8_t* encoded,
                  size_t lenEncodedBytes,
                  int16_t* decoded,
                  int16_t* speechType,
                  int16_t isRCUPayload) {
  /* Number of samples (480 or 960), output from decoder
     that were actually used in the encoder/decoder
     (determined on the fly). */
  int16_t numSamplesLB;
  int16_t numSamplesUB;
  int16_t speechIdx;
  float outFrame[MAX_FRAMESAMPLES];
  int16_t outFrameLB[MAX_FRAMESAMPLES];
  int16_t outFrameUB[MAX_FRAMESAMPLES];
  int numDecodedBytesLBint;
  size_t numDecodedBytesLB;
  int numDecodedBytesUB;
  size_t lenEncodedLBBytes;
  int16_t validChecksum = 1;
  int16_t k;
  uint16_t numLayer;
  size_t totSizeBytes;
  int16_t err;

  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  ISACUBDecStruct* decInstUB = &(instISAC->instUB.ISACdecUB_obj);
  ISACLBDecStruct* 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 encoded 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, encoded,
         lenEncodedLBBytes);

  /* We need to initialize numSamplesLB to something; otherwise, in the test
     for whether we should return -1 below, the compiler might generate code
     that fools Memcheck (Valgrind) into thinking that the control flow depends
     on the uninitialized value in numSamplesLB (since WebRtcIsac_DecodeLb will
     not fill it in if it fails and returns -1). */
  numSamplesLB = 0;

  /* 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. */
  numDecodedBytesLBint = WebRtcIsac_DecodeLb(&instISAC->transform_tables,
                                             outFrame, decInstLB,
                                             &numSamplesLB, isRCUPayload);
  numDecodedBytesLB = (size_t)numDecodedBytesLBint;
  if ((numDecodedBytesLBint < 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 without this the number
   * of iterations is limited. */
  numLayer = 1;
  totSizeBytes = numDecodedBytesLB;
  while (totSizeBytes != lenEncodedBytes) {
    if ((totSizeBytes > lenEncodedBytes) ||
        (encoded[totSizeBytes] == 0) ||
        (numLayer > MAX_NUM_LAYERS)) {
      instISAC->errorCode = ISAC_LENGTH_MISMATCH;
      return -1;
    }
    totSizeBytes += encoded[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] = (int16_t)WebRtcIsac_lrint(outFrame[k]);
      }
    }
    numSamplesUB = 0;
  } else {
    uint32_t 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] = (int16_t)WebRtcIsac_lrint(outFrame[k]);
      }
    }

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

      /* Prepare for the potential increase of signal bandwidth. */
      instISAC->resetFlag_8kHz = 2;
    } else {
      /* This includes the checksum and the bytes that stores the length. */
      int16_t lenNextStream = encoded[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((int16_t*)(&encoded[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) ==
                            encoded[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(int16_t) * numSamplesUB);
      } else {
        /* A valid super-wideband biststream exists. */
        enum ISACBandwidth bandwidthKHz;
        int32_t maxDelayBit;

        /* 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,
               &encoded[numDecodedBytesLB + 1], lenNextStream);

        /* Reset bit-stream object, this is the first decoding. */
        WebRtcIsac_ResetBitstream(&(decInstUB->bitstr_obj));

        /* Decode jitter information. */
        err = WebRtcIsac_DecodeJitterInfo(&decInstUB->bitstr_obj, &maxDelayBit);
        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 embedded 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(
                &instISAC->transform_tables, 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(
                &instISAC->transform_tables, outFrame, decInstUB, isRCUPayload);
            break;
          }
          default:
            return -1;
        }

        if (numDecodedBytesUB < 0) {
          instISAC->errorCode = numDecodedBytesUB;
          return -1;
        }
        if (numDecodedBytesLB + numDecodedBytesUB > lenEncodedBytes) {
          // We have supposedly decoded more bytes than we were given. Likely
          // caused by bad input data.
          instISAC->errorCode = ISAC_LENGTH_MISMATCH;
          return -1;
        }

        /* It might be less due to garbage. */
        if ((numDecodedBytesUB != lenNextStream) &&
            (numDecodedBytesUB != (lenNextStream -
                encoded[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] = (int16_t)WebRtcIsac_lrint(
                              outFrame[k]);
          }
        }
      }
    }

    speechIdx = 0;
    while (speechIdx < numSamplesLB) {
      WebRtcSpl_SynthesisQMF(&outFrameLB[speechIdx], &outFrameUB[speechIdx],
                             FRAMESAMPLES_10ms, &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
 */

int WebRtcIsac_Decode(ISACStruct* ISAC_main_inst,
                      const uint8_t* encoded,
                      size_t lenEncodedBytes,
                      int16_t* decoded,
                      int16_t* speechType) {
  int16_t 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 in 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
 */



int WebRtcIsac_DecodeRcu(ISACStruct* ISAC_main_inst,
                         const uint8_t* encoded,
                         size_t lenEncodedBytes,
                         int16_t* decoded,
                         int16_t* speechType) {
  int16_t 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               : Number of samples in decoded PLC vector
 */
size_t WebRtcIsac_DecodePlc(ISACStruct* ISAC_main_inst,
                            int16_t* decoded,
                            size_t noOfLostFrames) {
  size_t numSamples = 0;
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;

  /* Limit number of frames to two = 60 millisecond.
   * 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;
    }
  }

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


/****************************************************************************
 * ControlLb(...) - Internal function for controlling Lower Band
 * ControlUb(...) - Internal function for controlling 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 int16_t ControlLb(ISACLBStruct* instISAC, double rate,
                         int16_t 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 int16_t ControlUb(ISACUBStruct* instISAC, double rate) {
  if ((rate >= 10000) && (rate <= 32000)) {
    instISAC->ISACencUB_obj.bottleneck = rate;
  } else {
    return -ISAC_DISALLOWED_BOTTLENECK;
  }
  return 0;
}

int16_t WebRtcIsac_Control(ISACStruct* ISAC_main_inst,
                           int32_t bottleneckBPS,
                           int frameSize) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  int16_t status;
  double rateLB;
  double rateUB;
  enum ISACBandwidth bandwidthKHz;

  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, (int16_t)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 if the bandwidth is changing. */
  if (instISAC->bandwidthKHz != bandwidthKHz) {
    instISAC->bandwidthKHz = bandwidthKHz;
    UpdatePayloadSizeLimit(instISAC);
  }
  instISAC->bottleneck = bottleneckBPS;
  return 0;
}

void WebRtcIsac_SetInitialBweBottleneck(ISACStruct* ISAC_main_inst,
                                        int bottleneck_bits_per_second) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  RTC_DCHECK_GE(bottleneck_bits_per_second, 10000);
  RTC_DCHECK_LE(bottleneck_bits_per_second, 32000);
  instISAC->bwestimator_obj.send_bw_avg = (float)bottleneck_bits_per_second;
}

/****************************************************************************
 * 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
 */
int16_t WebRtcIsac_ControlBwe(ISACStruct* ISAC_main_inst,
                              int32_t bottleneckBPS,
                              int frameSizeMs,
                              int16_t enforceFrameSize) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  enum ISACBandwidth bandwidth;

   /* 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 structure variable if enforceFrameSize is set. ISAC will then
   * keep the chosen frame size. */
  if (enforceFrameSize != 0) {
    instISAC->instLB.ISACencLB_obj.enforceFrameSize = 1;
  } else {
    instISAC->instLB.ISACencLB_obj.enforceFrameSize = 0;
  }

  /* Set the initial rate. If the input value is zero then the default intial
   * rate is used. Otehrwise, values between 10 to 32 kbps are accepted. */
  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 the initial frame-size. If 'enforceFrameSize' is set, the frame-size
   *  will not change */
  if (frameSizeMs != 0) {
    if ((frameSizeMs  == 30) || (frameSizeMs == 60)) {
      instISAC->instLB.ISACencLB_obj.new_framelength =
          (int16_t)((FS / 1000) * frameSizeMs);
    } else {
      instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH;
      return -1;
    }
  }
  return 0;
}


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

  /* Check if encoder initialized. */
  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 structure
 *        - rateIndex         : Bandwidth estimate from other side.
 *
 * Return value               : 0 - ok
 *                             -1 - index out of range
 */
int16_t WebRtcIsac_UpdateUplinkBw(ISACStruct* ISAC_main_inst,
                                  int16_t bweIndex) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  int16_t returnVal;

  /* 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
 * bit-stream.
 *
 * Input:
 *        - encoded           : Encoded bit-stream
 *
 * Output:
 *        - frameLength       : Length of frame in packet (in samples)
 *        - bweIndex          : Bandwidth estimate in bit-stream
 *
 */
int16_t WebRtcIsac_ReadBwIndex(const uint8_t* encoded,
                               int16_t* bweIndex) {
  Bitstr streamdata;
#ifndef WEBRTC_ARCH_BIG_ENDIAN
  int k;
#endif
  int16_t err;

  WebRtcIsac_ResetBitstream(&(streamdata));

#ifndef WEBRTC_ARCH_BIG_ENDIAN
  for (k = 0; k < 10; k++) {
    int16_t ek2 = ((const int16_t*)encoded)[k >> 1];
    streamdata.stream[k] = (uint8_t)((ek2 >> ((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 number of samples the decoder will generate if
 * the given payload is decoded.
 *
 * Input:
 *        - encoded           : Encoded bitstream
 *
 * Output:
 *        - frameLength       : Length of frame in packet (in samples)
 *
 */
int16_t WebRtcIsac_ReadFrameLen(ISACStruct* ISAC_main_inst,
                                const uint8_t* encoded,
                                int16_t* frameLength) {
  Bitstr streamdata;
#ifndef WEBRTC_ARCH_BIG_ENDIAN
  int k;
#endif
  int16_t err;
  ISACMainStruct* instISAC;

  WebRtcIsac_ResetBitstream(&(streamdata));

#ifndef WEBRTC_ARCH_BIG_ENDIAN
  for (k = 0; k < 10; k++) {
    int16_t ek2 = ((const int16_t*)encoded)[k >> 1];
    streamdata.stream[k] = (uint8_t)((ek2 >> ((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(...)
 *
 * This function returns the frame length (in samples) of the next packet.
 * In the case of channel-adaptive mode, iSAC decides on its frame length based
 * on the estimated bottleneck, this AOI 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
 *
 */
int16_t WebRtcIsac_GetNewFrameLen(ISACStruct* ISAC_main_inst) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;

  /* Return new frame length. */
  if (instISAC->in_sample_rate_hz == 16000)
    return (instISAC->instLB.ISACencLB_obj.new_framelength);
  else  /* 32000 Hz */
    return ((instISAC->instLB.ISACencLB_obj.new_framelength) * 2);
}


/****************************************************************************
 * WebRtcIsac_GetErrorCode(...)
 *
 * This function can be used to check the error code of an iSAC instance.
 * When a function returns -1 an error code will be set for that instance.
 * The function below extracts the code of the last error that occurred in
 * the specified instance.
 *
 * Input:
 *        - ISAC_main_inst    : ISAC instance
 *
 * Return value               : Error code
 */
int16_t WebRtcIsac_GetErrorCode(ISACStruct* ISAC_main_inst) {
 return ((ISACMainStruct*)ISAC_main_inst)->errorCode;
}


/****************************************************************************
 * WebRtcIsac_GetUplinkBw(...)
 *
 * This function outputs the target bottleneck of the codec. In
 * channel-adaptive mode, the target bottleneck is specified through an in-band
 * signalling retrieved 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 are used.).
 * Note that the output is the iSAC internal operating bottleneck which 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.
 */
int16_t WebRtcIsac_GetUplinkBw(ISACStruct*  ISAC_main_inst,
                               int32_t* bottleneck) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;

  if (instISAC->codingMode == 0) {
    /* We are in adaptive mode then get the bottleneck from BWE. */
    *bottleneck = (int32_t)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
 */
int16_t WebRtcIsac_SetMaxPayloadSize(ISACStruct* ISAC_main_inst,
                                     int16_t maxPayloadBytes) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  int16_t status = 0;

  /* 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
 */
int16_t WebRtcIsac_SetMaxRate(ISACStruct* ISAC_main_inst,
                              int32_t maxRate) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  int16_t maxRateInBytesPer30Ms;
  int16_t status = 0;

  /* 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 = (int16_t)(maxRate * 3 / 800);

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

    if (maxRate > 53400) {
      /* 'maxRate' 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(...)
 *
 * This function populates "encoded" with the redundant payload of the recently
 * encodedframe. 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
 */
int16_t WebRtcIsac_GetRedPayload(ISACStruct* ISAC_main_inst,
                                 uint8_t* encoded) {
  Bitstr iSACBitStreamInst;
  int16_t streamLenLB;
  int16_t streamLenUB;
  int16_t streamLen;
  int16_t totalLenUB;
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
#ifndef WEBRTC_ARCH_BIG_ENDIAN
  int k;
#endif

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

  WebRtcIsac_ResetBitstream(&(iSACBitStreamInst));

  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 int16_t. */
  memcpy(encoded, 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 includes the bit-stream 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)) {
    uint32_t crc;
    streamLen += totalLenUB;
    encoded[streamLenLB] = (uint8_t)totalLenUB;
    memcpy(&encoded[streamLenLB + 1], iSACBitStreamInst.stream,
           streamLenUB);

    WebRtcIsac_GetCrc((int16_t*)(&(encoded[streamLenLB + 1])),
                      streamLenUB, &crc);
#ifndef WEBRTC_ARCH_BIG_ENDIAN
    for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) {
      encoded[streamLen - LEN_CHECK_SUM_WORD8 + k] =
        (uint8_t)((crc >> (24 - k * 8)) & 0xFF);
    }
#else
    memcpy(&encoded[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()
 * This function sets 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 be reset to their default values.
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *        - sample_rate_hz    : sampling rate in Hertz, valid values are 16000
 *                              and 32000.
 *
 * Return value               : 0 if successful
 *                             -1 if failed.
 */
int16_t WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst,
                                  uint16_t sample_rate_hz) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  enum IsacSamplingRate encoder_operational_rate;

  if ((sample_rate_hz != 16000) && (sample_rate_hz != 32000)) {
    /* Sampling Frequency is not supported. */
    instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY;
    return -1;
  }
  if (sample_rate_hz == 16000) {
    encoder_operational_rate = kIsacWideband;
  } else {
    encoder_operational_rate = kIsacSuperWideband;
  }

  if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
      BIT_MASK_ENC_INIT) {
    if (encoder_operational_rate == kIsacWideband) {
      instISAC->bandwidthKHz = isac8kHz;
    } else {
      instISAC->bandwidthKHz = isac16kHz;
    }
  } else {
    ISACUBStruct* instUB = &(instISAC->instUB);
    ISACLBStruct* instLB = &(instISAC->instLB);
    int32_t bottleneck = instISAC->bottleneck;
    int16_t codingMode = instISAC->codingMode;
    int16_t frameSizeMs = instLB->ISACencLB_obj.new_framelength /
        (FS / 1000);

    if ((encoder_operational_rate == 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 ((encoder_operational_rate == kIsacSuperWideband) &&
               (instISAC->encoderSamplingRateKHz == kIsacWideband)) {
      double bottleneckLB = 0;
      double bottleneckUB = 0;
      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, encoder_operational_rate);
      EncoderInitUb(instUB, instISAC->bandwidthKHz);

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

      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 = encoder_operational_rate;
  instISAC->in_sample_rate_hz = sample_rate_hz;
  return 0;
}


/******************************************************************************
 * WebRtcIsac_SetDecSampRate()
 * This function sets 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
 *        - sample_rate_hz    : sampling rate in Hertz, valid values are 16000
 *                              and 32000.
 *
 * Return value               : 0 if successful
 *                             -1 if failed.
 */
int16_t WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst,
                                  uint16_t sample_rate_hz) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  enum IsacSamplingRate decoder_operational_rate;

  if (sample_rate_hz == 16000) {
    decoder_operational_rate = kIsacWideband;
  } else if (sample_rate_hz == 32000) {
    decoder_operational_rate = kIsacSuperWideband;
  } else {
    /* Sampling Frequency is not supported. */
    instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY;
    return -1;
  }

  if ((instISAC->decoderSamplingRateKHz == kIsacWideband) &&
        (decoder_operational_rate == 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(int32_t));
      memset(instISAC->synthesisFBState2, 0,
             FB_STATE_SIZE_WORD32 * sizeof(int32_t));

      DecoderInitUb(&instISAC->instUB);
  }
  instISAC->decoderSamplingRateKHz = decoder_operational_rate;
  return 0;
}


/******************************************************************************
 * WebRtcIsac_EncSampRate()
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *
 * Return value               : sampling rate in Hertz. The input to encoder
 *                              is expected to be sampled in this rate.
 *
 */
uint16_t WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  return instISAC->in_sample_rate_hz;
}


/******************************************************************************
 * WebRtcIsac_DecSampRate()
 * Return the sampling rate of the decoded audio.
 *
 * Input:
 *        - ISAC_main_inst    : iSAC instance
 *
 * Return value               : sampling rate in Hertz. Decoder output is
 *                              sampled at this rate.
 *
 */
uint16_t WebRtcIsac_DecSampRate(ISACStruct* ISAC_main_inst) {
  ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
  return instISAC->decoderSamplingRateKHz == kIsacWideband ? 16000 : 32000;
}

void WebRtcIsac_GetBandwidthInfo(ISACStruct* inst,
                                 IsacBandwidthInfo* bwinfo) {
  ISACMainStruct* instISAC = (ISACMainStruct*)inst;
  RTC_DCHECK_NE(0, instISAC->initFlag & BIT_MASK_DEC_INIT);
  WebRtcIsacBw_GetBandwidthInfo(&instISAC->bwestimator_obj,
                                instISAC->decoderSamplingRateKHz, bwinfo);
}

void WebRtcIsac_SetBandwidthInfo(ISACStruct* inst,
                                 const IsacBandwidthInfo* bwinfo) {
  ISACMainStruct* instISAC = (ISACMainStruct*)inst;
  RTC_DCHECK_NE(0, instISAC->initFlag & BIT_MASK_ENC_INIT);
  WebRtcIsacBw_SetBandwidthInfo(&instISAC->bwestimator_obj, bwinfo);
}

void WebRtcIsac_SetEncSampRateInDecoder(ISACStruct* inst,
                                        int sample_rate_hz) {
  ISACMainStruct* instISAC = (ISACMainStruct*)inst;
  RTC_DCHECK_NE(0, instISAC->initFlag & BIT_MASK_DEC_INIT);
  RTC_DCHECK(!(instISAC->initFlag & BIT_MASK_ENC_INIT));
  RTC_DCHECK(sample_rate_hz == 16000 || sample_rate_hz == 32000);
  instISAC->encoderSamplingRateKHz = sample_rate_hz / 1000;
}
