/*
 *  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.
 */

/*
 * encode.c
 *
 * This file contains definition of funtions for encoding.
 * Decoding of upper-band, including 8-12 kHz, when the bandwidth is
 * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz.
 *
 */

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

#include "structs.h"
#include "codec.h"
#include "pitch_estimator.h"
#include "entropy_coding.h"
#include "arith_routines.h"
#include "pitch_gain_tables.h"
#include "pitch_lag_tables.h"
#include "spectrum_ar_model_tables.h"
#include "lpc_tables.h"
#include "lpc_analysis.h"
#include "bandwidth_estimator.h"
#include "lpc_shape_swb12_tables.h"
#include "lpc_shape_swb16_tables.h"
#include "lpc_gain_swb_tables.h"


#define UB_LOOKAHEAD 24


/*
  Rate allocation tables of lower and upper-band bottleneck for
  12kHz & 16kHz bandwidth.

  12 kHz bandwidth
  -----------------
  The overall bottleneck of the coder is between 38 kbps and 45 kbps. We have
  considered 7 enteries, uniformly distributed in this interval, i.e. 38,
  39.17, 40.33, 41.5, 42.67, 43.83 and 45. For every entery, the lower-band
  and the upper-band bottlenecks are specified in
  'kLowerBandBitRate12' and 'kUpperBandBitRate12'
  tables, respectively. E.g. the overall rate of 41.5 kbps corresponts to a
  bottleneck of 31 kbps for lower-band and 27 kbps for upper-band. Given an
  overall bottleneck of the codec, we use linear interpolation to get
  lower-band and upper-band bottlenecks.

  16 kHz bandwidth
  -----------------
  The overall bottleneck of the coder is between 50 kbps and 56 kbps. We have
  considered 7 enteries, uniformly distributed in this interval, i.e. 50, 51.2,
  52.4, 53.6, 54.8 and 56. For every entery, the lower-band and the upper-band
  bottlenecks are specified in 'kLowerBandBitRate16' and
  'kUpperBandBitRate16' tables, respectively. E.g. the overall rate
  of 53.6 kbps corresponts to a bottleneck of 32 kbps for lower-band and 30
  kbps for upper-band. Given an overall bottleneck of the codec, we use linear
  interpolation to get lower-band and upper-band bottlenecks.

 */

/*     38  39.17  40.33   41.5  42.67  43.83     45 */
static const int16_t kLowerBandBitRate12[7] = {
    29000, 30000, 30000, 31000, 31000, 32000, 32000 };
static const int16_t kUpperBandBitRate12[7] = {
    25000, 25000, 27000, 27000, 29000, 29000, 32000 };

/*    50     51.2  52.4   53.6   54.8    56 */
static const int16_t kLowerBandBitRate16[6] = {
    31000, 31000, 32000, 32000, 32000, 32000 };
static const int16_t kUpperBandBitRate16[6] = {
    28000, 29000, 29000, 30000, 31000, 32000 };

/******************************************************************************
 * WebRtcIsac_RateAllocation()
 * Internal function to perform a rate-allocation for upper and lower-band,
 * given a total rate.
 *
 * Input:
 *   - inRateBitPerSec           : a total bottleneck in bits/sec.
 *
 * Output:
 *   - rateLBBitPerSec           : a bottleneck allocated to the lower-band
 *                                 in bits/sec.
 *   - rateUBBitPerSec           : a bottleneck allocated to the upper-band
 *                                 in bits/sec.
 *
 * Return value                  : 0 if rate allocation has been successful.
 *                                -1 if failed to allocate rates.
 */

int16_t WebRtcIsac_RateAllocation(int32_t inRateBitPerSec,
                                        double* rateLBBitPerSec,
                                        double* rateUBBitPerSec,
                                        enum ISACBandwidth* bandwidthKHz) {
  int16_t idx;
  double idxD;
  double idxErr;
  if (inRateBitPerSec < 38000) {
    /* If the given overall bottleneck is less than 38000 then
     * then codec has to operate in wideband mode, i.e. 8 kHz
     * bandwidth. */
    *rateLBBitPerSec = (int16_t)((inRateBitPerSec > 32000) ?
        32000 : inRateBitPerSec);
    *rateUBBitPerSec = 0;
    *bandwidthKHz = isac8kHz;
  } else if ((inRateBitPerSec >= 38000) && (inRateBitPerSec < 50000)) {
    /* At a bottleneck between 38 and 50 kbps the codec is operating
     * at 12 kHz bandwidth. Using xxxBandBitRate12[] to calculates
     * upper/lower bottleneck */

    /* Find the bottlenecks by linear interpolation,
     * step is (45000 - 38000)/6.0 we use the inverse of it. */
    const double stepSizeInv = 8.5714286e-4;
    idxD = (inRateBitPerSec - 38000) * stepSizeInv;
    idx = (idxD >= 6) ? 6 : ((int16_t)idxD);
    idxErr = idxD - idx;
    *rateLBBitPerSec = kLowerBandBitRate12[idx];
    *rateUBBitPerSec = kUpperBandBitRate12[idx];

    if (idx < 6) {
      *rateLBBitPerSec += (int16_t)(
          idxErr * (kLowerBandBitRate12[idx + 1] - kLowerBandBitRate12[idx]));
      *rateUBBitPerSec += (int16_t)(
          idxErr * (kUpperBandBitRate12[idx + 1] - kUpperBandBitRate12[idx]));
    }
    *bandwidthKHz = isac12kHz;
  } else if ((inRateBitPerSec >= 50000) && (inRateBitPerSec <= 56000)) {
    /* A bottleneck between 50 and 56 kbps corresponds to bandwidth
     * of 16 kHz. Using xxxBandBitRate16[] to calculates
     * upper/lower bottleneck. */

    /* Find the bottlenecks by linear interpolation
     * step is (56000 - 50000)/5 we use the inverse of it. */
    const double stepSizeInv = 8.3333333e-4;
    idxD = (inRateBitPerSec - 50000) * stepSizeInv;
    idx = (idxD >= 5) ? 5 : ((int16_t)idxD);
    idxErr = idxD - idx;
    *rateLBBitPerSec = kLowerBandBitRate16[idx];
    *rateUBBitPerSec  = kUpperBandBitRate16[idx];

    if (idx < 5) {
      *rateLBBitPerSec += (int16_t)(idxErr *
          (kLowerBandBitRate16[idx + 1] -
              kLowerBandBitRate16[idx]));

      *rateUBBitPerSec += (int16_t)(idxErr *
          (kUpperBandBitRate16[idx + 1] -
              kUpperBandBitRate16[idx]));
    }
    *bandwidthKHz = isac16kHz;
  } else {
    /* Out-of-range botlteneck value. */
    return -1;
  }

  /* limit the values. */
  *rateLBBitPerSec = (*rateLBBitPerSec > 32000) ? 32000 : *rateLBBitPerSec;
  *rateUBBitPerSec = (*rateUBBitPerSec > 32000) ? 32000 : *rateUBBitPerSec;
  return 0;
}


void WebRtcIsac_ResetBitstream(Bitstr* bit_stream) {
  bit_stream->W_upper = 0xFFFFFFFF;
  bit_stream->stream_index = 0;
  bit_stream->streamval = 0;
}

int WebRtcIsac_EncodeLb(const TransformTables* transform_tables,
                        float* in, ISACLBEncStruct* ISACencLB_obj,
                        int16_t codingMode,
                        int16_t bottleneckIndex) {
  int stream_length = 0;
  int err;
  int k;
  int iterCntr;

  double lofilt_coef[(ORDERLO + 1)*SUBFRAMES];
  double hifilt_coef[(ORDERHI + 1)*SUBFRAMES];
  float LP[FRAMESAMPLES_HALF];
  float HP[FRAMESAMPLES_HALF];

  double LP_lookahead[FRAMESAMPLES_HALF];
  double HP_lookahead[FRAMESAMPLES_HALF];
  double LP_lookahead_pf[FRAMESAMPLES_HALF + QLOOKAHEAD];
  double LPw[FRAMESAMPLES_HALF];

  double HPw[FRAMESAMPLES_HALF];
  double LPw_pf[FRAMESAMPLES_HALF];
  int16_t fre[FRAMESAMPLES_HALF];   /* Q7 */
  int16_t fim[FRAMESAMPLES_HALF];   /* Q7 */

  double PitchLags[4];
  double PitchGains[4];
  int16_t PitchGains_Q12[4];
  int16_t AvgPitchGain_Q12;

  int frame_mode; /* 0 for 30ms, 1 for 60ms */
  int status = 0;
  int my_index;
  transcode_obj transcodingParam;
  double bytesLeftSpecCoding;
  uint16_t payloadLimitBytes;

  /* Copy new frame-length and bottleneck rate only for the first 10 ms data */
  if (ISACencLB_obj->buffer_index == 0) {
    /* Set the framelength for the next packet. */
    ISACencLB_obj->current_framesamples = ISACencLB_obj->new_framelength;
  }
  /* 'frame_mode' is 0 (30 ms) or 1 (60 ms). */
  frame_mode = ISACencLB_obj->current_framesamples / MAX_FRAMESAMPLES;

  /* buffer speech samples (by 10ms packet) until the frame-length */
  /* is reached (30 or 60 ms).                                     */
  /*****************************************************************/

  /* fill the buffer with 10ms input data */
  for (k = 0; k < FRAMESAMPLES_10ms; k++) {
    ISACencLB_obj->data_buffer_float[k + ISACencLB_obj->buffer_index] = in[k];
  }

  /* If buffersize is not equal to current framesize then increase index
   * and return. We do no encoding untill we have enough audio.  */
  if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != FRAMESAMPLES) {
    ISACencLB_obj->buffer_index += FRAMESAMPLES_10ms;
    return 0;
  }
  /* If buffer reached the right size, reset index and continue with
   * encoding the frame. */
  ISACencLB_obj->buffer_index = 0;

  /* End of buffer function. */
  /**************************/

  /* Encoding */
  /************/

  if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
    /* This is to avoid Linux warnings until we change 'int' to 'Word32'
     * at all places. */
    int intVar;
    /* reset bitstream */
    WebRtcIsac_ResetBitstream(&(ISACencLB_obj->bitstr_obj));

    if ((codingMode == 0) && (frame_mode == 0) &&
        (ISACencLB_obj->enforceFrameSize == 0)) {
      ISACencLB_obj->new_framelength = WebRtcIsac_GetNewFrameLength(
          ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
    }

    ISACencLB_obj->s2nr = WebRtcIsac_GetSnr(
        ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);

    /* Encode frame length. */
    status = WebRtcIsac_EncodeFrameLen(
        ISACencLB_obj->current_framesamples, &ISACencLB_obj->bitstr_obj);
    if (status < 0) {
      /* Wrong frame size. */
      return status;
    }
    /* Save framelength for multiple packets memory. */
    ISACencLB_obj->SaveEnc_obj.framelength =
        ISACencLB_obj->current_framesamples;

    /* To be used for Redundant Coding. */
    ISACencLB_obj->lastBWIdx = bottleneckIndex;
    intVar = (int)bottleneckIndex;
    WebRtcIsac_EncodeReceiveBw(&intVar, &ISACencLB_obj->bitstr_obj);
  }

  /* Split signal in two bands. */
  WebRtcIsac_SplitAndFilterFloat(ISACencLB_obj->data_buffer_float, LP, HP,
                                 LP_lookahead, HP_lookahead,
                                 &ISACencLB_obj->prefiltbankstr_obj);

  /* estimate pitch parameters and pitch-filter lookahead signal */
  WebRtcIsac_PitchAnalysis(LP_lookahead, LP_lookahead_pf,
                           &ISACencLB_obj->pitchanalysisstr_obj, PitchLags,
                           PitchGains);

  /* Encode in FIX Q12. */

  /* Convert PitchGain to Fixed point. */
  for (k = 0; k < PITCH_SUBFRAMES; k++) {
    PitchGains_Q12[k] = (int16_t)(PitchGains[k] * 4096.0);
  }

  /* Set where to store data in multiple packets memory. */
  if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
    ISACencLB_obj->SaveEnc_obj.startIdx = 0;
  } else {
    ISACencLB_obj->SaveEnc_obj.startIdx = 1;
  }

  /* Quantize & encode pitch parameters. */
  WebRtcIsac_EncodePitchGain(PitchGains_Q12, &ISACencLB_obj->bitstr_obj,
                             &ISACencLB_obj->SaveEnc_obj);
  WebRtcIsac_EncodePitchLag(PitchLags, PitchGains_Q12,
                            &ISACencLB_obj->bitstr_obj,
                            &ISACencLB_obj->SaveEnc_obj);

  AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
      PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;

  /* Find coefficients for perceptual pre-filters. */
  WebRtcIsac_GetLpcCoefLb(LP_lookahead_pf, HP_lookahead,
                          &ISACencLB_obj->maskfiltstr_obj, ISACencLB_obj->s2nr,
                          PitchGains_Q12, lofilt_coef, hifilt_coef);

  /* Code LPC model and shape - gains not quantized yet. */
  WebRtcIsac_EncodeLpcLb(lofilt_coef, hifilt_coef, &ISACencLB_obj->bitstr_obj,
                         &ISACencLB_obj->SaveEnc_obj);

  /* Convert PitchGains back to FLOAT for pitchfilter_pre. */
  for (k = 0; k < 4; k++) {
    PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
  }

  /* Store the state of arithmetic coder before coding LPC gains. */
  transcodingParam.W_upper = ISACencLB_obj->bitstr_obj.W_upper;
  transcodingParam.stream_index = ISACencLB_obj->bitstr_obj.stream_index;
  transcodingParam.streamval = ISACencLB_obj->bitstr_obj.streamval;
  transcodingParam.stream[0] =
      ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
                                       2];
  transcodingParam.stream[1] =
      ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
                                       1];
  transcodingParam.stream[2] =
      ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index];

  /* Store LPC Gains before encoding them. */
  for (k = 0; k < SUBFRAMES; k++) {
    transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
    transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
  }

  /* Code gains */
  WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef,
                             &ISACencLB_obj->bitstr_obj,
                             &ISACencLB_obj->SaveEnc_obj);

  /* Get the correct value for the payload limit and calculate the
   * number of bytes left for coding the spectrum. */
  if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) {
    /* It is a 60ms and we are in the first 30ms then the limit at
     * this point should be half of the assigned value. */
    payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 >> 1;
  } else if (frame_mode == 0) {
    /* It is a 30ms frame */
    /* Subract 3 because termination process may add 3 bytes. */
    payloadLimitBytes = ISACencLB_obj->payloadLimitBytes30 - 3;
  } else {
    /* This is the second half of a 60ms frame. */
    /* Subract 3 because termination process may add 3 bytes. */
    payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 - 3;
  }
  bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;

  /* Perceptual pre-filtering (using normalized lattice filter). */
  /* Low-band filtering. */
  WebRtcIsac_NormLatticeFilterMa(ORDERLO,
                                 ISACencLB_obj->maskfiltstr_obj.PreStateLoF,
                                 ISACencLB_obj->maskfiltstr_obj.PreStateLoG,
                                 LP, lofilt_coef, LPw);
  /* High-band filtering. */
  WebRtcIsac_NormLatticeFilterMa(ORDERHI,
                                 ISACencLB_obj->maskfiltstr_obj.PreStateHiF,
                                 ISACencLB_obj->maskfiltstr_obj.PreStateHiG,
                                 HP, hifilt_coef, HPw);
  /* Pitch filter. */
  WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj,
                            PitchLags, PitchGains);
  /* Transform */
  WebRtcIsac_Time2Spec(transform_tables,
                       LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj);

  /* Save data for multiple packets memory. */
  my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
  memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
  memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));

  ISACencLB_obj->SaveEnc_obj.AvgPitchGain[ISACencLB_obj->SaveEnc_obj.startIdx] =
      AvgPitchGain_Q12;

  /* Quantization and loss-less coding. */
  err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
                              &ISACencLB_obj->bitstr_obj);
  if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    /* There has been an error but it was not too large payload
       (we can cure too large payload). */
    if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) {
      /* If this is the second 30ms of a 60ms frame reset
         this such that in the next call encoder starts fresh. */
      ISACencLB_obj->frame_nb = 0;
    }
    return err;
  }
  iterCntr = 0;
  while ((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
      (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    double bytesSpecCoderUsed;
    double transcodeScale;

    if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
      /* We were not able to limit the payload size */
      if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) {
        /* This was the first 30ms of a 60ms frame. Although
           the payload is larger than it should be but we let
           the second 30ms be encoded. Maybe together we
           won't exceed the limit. */
        ISACencLB_obj->frame_nb = 1;
        return 0;
      } else if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) {
        ISACencLB_obj->frame_nb = 0;
      }

      if (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
        return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
      } else {
        return status;
      }
    }

    if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
      bytesSpecCoderUsed = STREAM_SIZE_MAX;
      /* Being conservative */
      transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
    } else {
      bytesSpecCoderUsed = ISACencLB_obj->bitstr_obj.stream_index -
          transcodingParam.stream_index;
      transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
    }

    /* To be safe, we reduce the scale depending on
       the number of iterations. */
    transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
        (double)MAX_PAYLOAD_LIMIT_ITERATION));

    /* Scale the LPC Gains. */
    for (k = 0; k < SUBFRAMES; k++) {
      lofilt_coef[(LPC_LOBAND_ORDER + 1) * k] =
          transcodingParam.loFiltGain[k] * transcodeScale;
      hifilt_coef[(LPC_HIBAND_ORDER + 1) * k] =
          transcodingParam.hiFiltGain[k] * transcodeScale;
      transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
      transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
    }

    /* Scale DFT coefficients. */
    for (k = 0; k < FRAMESAMPLES_HALF; k++) {
      fre[k] = (int16_t)(fre[k] * transcodeScale);
      fim[k] = (int16_t)(fim[k] * transcodeScale);
    }

    /* Save data for multiple packets memory. */
    my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
    memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
    memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));

    /* Re-store the state of arithmetic coder before coding LPC gains. */
    ISACencLB_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
    ISACencLB_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
    ISACencLB_obj->bitstr_obj.streamval = transcodingParam.streamval;
    ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] =
        transcodingParam.stream[0];
    ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] =
        transcodingParam.stream[1];
    ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index] =
        transcodingParam.stream[2];

    /* Code gains. */
    WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef,
                               &ISACencLB_obj->bitstr_obj,
                               &ISACencLB_obj->SaveEnc_obj);

    /* Update the number of bytes left for encoding the spectrum. */
    bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;

    /* Encode the spectrum. */
    err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
                                &ISACencLB_obj->bitstr_obj);

    if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
      /* There has been an error but it was not too large
         payload (we can cure too large payload). */
      if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) {
        /* If this is the second 30 ms of a 60 ms frame reset
           this such that in the next call encoder starts fresh. */
        ISACencLB_obj->frame_nb = 0;
      }
      return err;
    }
    iterCntr++;
  }

  /* If 60 ms frame-size and just processed the first 30 ms, */
  /* go back to main function to buffer the other 30 ms speech frame. */
  if (frame_mode == 1) {
    if (ISACencLB_obj->frame_nb == 0) {
      ISACencLB_obj->frame_nb = 1;
      return 0;
    } else if (ISACencLB_obj->frame_nb == 1) {
      ISACencLB_obj->frame_nb = 0;
      /* Also update the frame-length for next packet,
         in Adaptive mode only. */
      if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) {
        ISACencLB_obj->new_framelength =
            WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck,
                                         ISACencLB_obj->current_framesamples);
      }
    }
  } else {
    ISACencLB_obj->frame_nb = 0;
  }

  /* Complete arithmetic coding. */
  stream_length = WebRtcIsac_EncTerminate(&ISACencLB_obj->bitstr_obj);
  return stream_length;
}



static int LimitPayloadUb(ISACUBEncStruct* ISACencUB_obj,
                          uint16_t payloadLimitBytes,
                          double bytesLeftSpecCoding,
                          transcode_obj* transcodingParam,
                          int16_t* fre, int16_t* fim,
                          double* lpcGains, enum ISACBand band, int status) {

  int iterCntr = 0;
  int k;
  double bytesSpecCoderUsed;
  double transcodeScale;
  const int16_t kAveragePitchGain = 0.0;

  do {
    if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
      /* We were not able to limit the payload size. */
      return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
    }

    if (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
      bytesSpecCoderUsed = STREAM_SIZE_MAX;
      /* Being conservative. */
      transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
    } else {
      bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index -
          transcodingParam->stream_index;
      transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
    }

    /* To be safe, we reduce the scale depending on the
       number of iterations. */
    transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
        (double)MAX_PAYLOAD_LIMIT_ITERATION));

    /* Scale the LPC Gains. */
    if (band == kIsacUpperBand16) {
      /* Two sets of coefficients if 16 kHz. */
      for (k = 0; k < SUBFRAMES; k++) {
        transcodingParam->loFiltGain[k] *= transcodeScale;
        transcodingParam->hiFiltGain[k] *= transcodeScale;
      }
    } else {
      /* One sets of coefficients if 12 kHz. */
      for (k = 0; k < SUBFRAMES; k++) {
        transcodingParam->loFiltGain[k] *= transcodeScale;
      }
    }

    /* Scale DFT coefficients. */
    for (k = 0; k < FRAMESAMPLES_HALF; k++) {
      fre[k] = (int16_t)(fre[k] * transcodeScale + 0.5);
      fim[k] = (int16_t)(fim[k] * transcodeScale + 0.5);
    }
    /* Store FFT coefficients for multiple encoding. */
    memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
          sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
    memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim,
           sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT));

    /* Store the state of arithmetic coder before coding LPC gains */
    ISACencUB_obj->bitstr_obj.W_upper = transcodingParam->W_upper;
    ISACencUB_obj->bitstr_obj.stream_index = transcodingParam->stream_index;
    ISACencUB_obj->bitstr_obj.streamval = transcodingParam->streamval;
    ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 2] =
        transcodingParam->stream[0];
    ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 1] =
        transcodingParam->stream[1];
    ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index] =
        transcodingParam->stream[2];

    /* Store the gains for multiple encoding. */
    memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
           SUBFRAMES * sizeof(double));
    /* Entropy Code lpc-gains, indices are stored for a later use.*/
    WebRtcIsac_EncodeLpcGainUb(transcodingParam->loFiltGain,
                               &ISACencUB_obj->bitstr_obj,
                               ISACencUB_obj->SaveEnc_obj.lpcGainIndex);

    /* If 16kHz should do one more set. */
    if (band == kIsacUpperBand16) {
      /* Store the gains for multiple encoding. */
      memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain[SUBFRAMES],
             &lpcGains[SUBFRAMES], SUBFRAMES * sizeof(double));
      /* Entropy Code lpc-gains, indices are stored for a later use.*/
      WebRtcIsac_EncodeLpcGainUb(
          transcodingParam->hiFiltGain, &ISACencUB_obj->bitstr_obj,
          &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]);
    }

    /* Update the number of bytes left for encoding the spectrum. */
    bytesLeftSpecCoding = payloadLimitBytes -
        ISACencUB_obj->bitstr_obj.stream_index;

    /* Save the bit-stream object at this point for FEC. */
    memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
           &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));

    /* Encode the spectrum. */
    status = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain,
                                   band, &ISACencUB_obj->bitstr_obj);
    if ((status < 0) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
      /* There has been an error but it was not too large payload
         (we can cure too large payload). */
      return status;
    }
    iterCntr++;
  } while ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
      (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH));
  return 0;
}

int WebRtcIsac_EncodeUb16(const TransformTables* transform_tables,
                          float* in, ISACUBEncStruct* ISACencUB_obj,
                          int32_t jitterInfo) {
  int err;
  int k;

  double lpcVecs[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
  double percepFilterParams[(1 + UB_LPC_ORDER) * (SUBFRAMES << 1) +
                            (1 + UB_LPC_ORDER)];

  double LP_lookahead[FRAMESAMPLES];
  int16_t fre[FRAMESAMPLES_HALF];   /* Q7 */
  int16_t fim[FRAMESAMPLES_HALF];   /* Q7 */

  int status = 0;

  double varscale[2];
  double corr[SUBFRAMES << 1][UB_LPC_ORDER + 1];
  double lpcGains[SUBFRAMES << 1];
  transcode_obj transcodingParam;
  uint16_t payloadLimitBytes;
  double s2nr;
  const int16_t kAveragePitchGain = 0.0;
  int bytesLeftSpecCoding;

  /* Buffer speech samples (by 10ms packet) until the frame-length is   */
  /* reached (30 ms).                                                   */
  /*********************************************************************/

  /* fill the buffer with 10ms input data */
  memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in,
         FRAMESAMPLES_10ms * sizeof(float));

  /* If buffer size is not equal to current frame-size, and end of file is
   * not reached yet, we don't do encoding unless we have the whole frame. */
  if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
    ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
    return 0;
  }

  /* End of buffer function. */
  /**************************/

  /* Encoding */
  /************/

  /* Reset bit-stream */
  WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));

  /* Encoding of bandwidth information. */
  WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);

  status = WebRtcIsac_EncodeBandwidth(isac16kHz, &ISACencUB_obj->bitstr_obj);
  if (status < 0) {
    return status;
  }

  s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);

  memcpy(lpcVecs, ISACencUB_obj->lastLPCVec, UB_LPC_ORDER * sizeof(double));

  for (k = 0; k < FRAMESAMPLES; k++) {
    LP_lookahead[k] = ISACencUB_obj->data_buffer_float[UB_LOOKAHEAD + k];
  }

  /* Find coefficients for perceptual pre-filters. */
  WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
                          &lpcVecs[UB_LPC_ORDER], corr, varscale, isac16kHz);

  memcpy(ISACencUB_obj->lastLPCVec,
         &lpcVecs[(UB16_LPC_VEC_PER_FRAME - 1) * (UB_LPC_ORDER)],
         sizeof(double) * UB_LPC_ORDER);

  /* Code LPC model and shape - gains not quantized yet. */
  WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
                         percepFilterParams, isac16kHz,
                         &ISACencUB_obj->SaveEnc_obj);

  /* the first set of lpc parameters are from the last sub-frame of
   * the previous frame. so we don't care about them. */
  WebRtcIsac_GetLpcGain(s2nr, &percepFilterParams[UB_LPC_ORDER + 1],
                        (SUBFRAMES << 1), lpcGains, corr, varscale);

  /* Store the state of arithmetic coder before coding LPC gains */
  transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
  transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
  transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
  transcodingParam.stream[0] =
      ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
                                       2];
  transcodingParam.stream[1] =
      ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
                                       1];
  transcodingParam.stream[2] =
      ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];

  /* Store LPC Gains before encoding them. */
  for (k = 0; k < SUBFRAMES; k++) {
    transcodingParam.loFiltGain[k] = lpcGains[k];
    transcodingParam.hiFiltGain[k] = lpcGains[SUBFRAMES + k];
  }

  /* Store the gains for multiple encoding. */
  memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
         (SUBFRAMES << 1) * sizeof(double));

  WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
                             ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
  WebRtcIsac_EncodeLpcGainUb(
      &lpcGains[SUBFRAMES], &ISACencUB_obj->bitstr_obj,
      &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]);

  /* Get the correct value for the payload limit and calculate the number of
     bytes left for coding the spectrum. It is a 30ms frame
     Subract 3 because termination process may add 3 bytes */
  payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
      ISACencUB_obj->numBytesUsed - 3;
  bytesLeftSpecCoding = payloadLimitBytes -
        ISACencUB_obj->bitstr_obj.stream_index;

  for (k = 0; k < (SUBFRAMES << 1); k++) {
    percepFilterParams[k * (UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] =
        lpcGains[k];
  }

  /* LPC filtering (using normalized lattice filter), */
  /* first half-frame. */
  WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
                                 ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
                                 ISACencUB_obj->maskfiltstr_obj.PreStateLoG,
                                 &ISACencUB_obj->data_buffer_float[0],
                                 &percepFilterParams[UB_LPC_ORDER + 1],
                                 &LP_lookahead[0]);

  /* Second half-frame filtering. */
  WebRtcIsac_NormLatticeFilterMa(
      UB_LPC_ORDER, ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
      ISACencUB_obj->maskfiltstr_obj.PreStateLoG,
      &ISACencUB_obj->data_buffer_float[FRAMESAMPLES_HALF],
      &percepFilterParams[(UB_LPC_ORDER + 1) + SUBFRAMES * (UB_LPC_ORDER + 1)],
      &LP_lookahead[FRAMESAMPLES_HALF]);

  WebRtcIsac_Time2Spec(transform_tables,
                       &LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF],
                       fre, fim, &ISACencUB_obj->fftstr_obj);

  /* Store FFT coefficients for multiple encoding. */
  memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, sizeof(fre));
  memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, sizeof(fim));

  /* Prepare the audio buffer for the next packet
   * move the last 3 ms to the beginning of the buffer. */
  memcpy(ISACencUB_obj->data_buffer_float,
         &ISACencUB_obj->data_buffer_float[FRAMESAMPLES],
         LB_TOTAL_DELAY_SAMPLES * sizeof(float));
  /* start writing with 3 ms delay to compensate for the delay
   * of the lower-band. */
  ISACencUB_obj->buffer_index = LB_TOTAL_DELAY_SAMPLES;

  /* Save the bit-stream object at this point for FEC. */
  memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, &ISACencUB_obj->bitstr_obj,
         sizeof(Bitstr));

  /* Qantization and lossless coding */
  /* Note that there is no pitch-gain for this band so kAveragePitchGain = 0
   * is passed to the function. In fact, the function ignores the 3rd parameter
   * for this band. */
  err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand16,
                              &ISACencUB_obj->bitstr_obj);
  if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    return err;
  }

  if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
      (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
                         &transcodingParam, fre, fim, lpcGains,
                         kIsacUpperBand16, err);
  }
  if (err < 0) {
    return err;
  }
  /* Complete arithmetic coding. */
  return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
}


int WebRtcIsac_EncodeUb12(const TransformTables* transform_tables,
                          float* in, ISACUBEncStruct* ISACencUB_obj,
                          int32_t jitterInfo) {
  int err;
  int k;

  double lpcVecs[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];

  double percepFilterParams[(1 + UB_LPC_ORDER) * SUBFRAMES];
  float LP[FRAMESAMPLES_HALF];
  float HP[FRAMESAMPLES_HALF];

  double LP_lookahead[FRAMESAMPLES_HALF];
  double HP_lookahead[FRAMESAMPLES_HALF];
  double LPw[FRAMESAMPLES_HALF];

  double HPw[FRAMESAMPLES_HALF];
  int16_t fre[FRAMESAMPLES_HALF];   /* Q7 */
  int16_t fim[FRAMESAMPLES_HALF];   /* Q7 */

  int status = 0;

  double varscale[1];

  double corr[UB_LPC_GAIN_DIM][UB_LPC_ORDER + 1];
  double lpcGains[SUBFRAMES];
  transcode_obj transcodingParam;
  uint16_t payloadLimitBytes;
  double s2nr;
  const int16_t kAveragePitchGain = 0.0;
  double bytesLeftSpecCoding;

  /* Buffer speech samples (by 10ms packet) until the framelength is  */
  /* reached (30 ms).                                                 */
  /********************************************************************/

  /* Fill the buffer with 10ms input data. */
  memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in,
         FRAMESAMPLES_10ms * sizeof(float));

  /* if buffer-size is not equal to current frame-size then increase the
     index and return. We do the encoding when we have enough audio.     */
  if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
    ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
    return 0;
  }
  /* If buffer reached the right size, reset index and continue
     with encoding the frame */
  ISACencUB_obj->buffer_index = 0;

  /* End of buffer function */
  /**************************/

  /* Encoding */
  /************/

  /* Reset bit-stream. */
  WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));

  /* Encoding bandwidth information. */
  WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
  status = WebRtcIsac_EncodeBandwidth(isac12kHz, &ISACencUB_obj->bitstr_obj);
  if (status < 0) {
    return status;
  }

  s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);

  /* Split signal in two bands. */
  WebRtcIsac_SplitAndFilterFloat(ISACencUB_obj->data_buffer_float, HP, LP,
                                 HP_lookahead, LP_lookahead,
                                 &ISACencUB_obj->prefiltbankstr_obj);

  /* Find coefficients for perceptual pre-filters. */
  WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
                          lpcVecs, corr, varscale, isac12kHz);

  /* Code LPC model and shape - gains not quantized yet. */
  WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
                         percepFilterParams, isac12kHz,
                         &ISACencUB_obj->SaveEnc_obj);

  WebRtcIsac_GetLpcGain(s2nr, percepFilterParams, SUBFRAMES, lpcGains, corr,
                        varscale);

  /* Store the state of arithmetic coder before coding LPC gains. */
  transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
  transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
  transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
  transcodingParam.stream[0] =
      ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
                                       2];
  transcodingParam.stream[1] =
      ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
                                       1];
  transcodingParam.stream[2] =
      ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];

  /* Store LPC Gains before encoding them. */
  for (k = 0; k < SUBFRAMES; k++) {
    transcodingParam.loFiltGain[k] = lpcGains[k];
  }

  /* Store the gains for multiple encoding. */
  memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES *
         sizeof(double));

  WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
                             ISACencUB_obj->SaveEnc_obj.lpcGainIndex);

  for (k = 0; k < SUBFRAMES; k++) {
    percepFilterParams[k * (UB_LPC_ORDER + 1)] = lpcGains[k];
  }

  /* perceptual pre-filtering (using normalized lattice filter) */
  /* low-band filtering */
  WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
                                 ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
                                 ISACencUB_obj->maskfiltstr_obj.PreStateLoG, LP,
                                 percepFilterParams, LPw);

  /* Get the correct value for the payload limit and calculate the number
     of bytes left for coding the spectrum. It is a 30ms frame Subract 3
     because termination process may add 3 bytes */
  payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
      ISACencUB_obj->numBytesUsed - 3;
  bytesLeftSpecCoding = payloadLimitBytes -
      ISACencUB_obj->bitstr_obj.stream_index;

  memset(HPw, 0, sizeof(HPw));

  /* Transform */
  WebRtcIsac_Time2Spec(transform_tables,
                       LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj);

  /* Store FFT coefficients for multiple encoding. */
  memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
         sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
  memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim,
         sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT));

  /* Save the bit-stream object at this point for FEC. */
  memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
         &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));

  /* Quantization and loss-less coding */
  /* The 4th parameter to this function is pitch-gain, which is only used
   * when encoding 0-8 kHz band, and irrelevant in this function, therefore,
   * we insert zero here. */
  err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand12,
                              &ISACencUB_obj->bitstr_obj);
  if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    /* There has been an error but it was not too large
       payload (we can cure too large payload) */
    return err;
  }

  if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
      (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
                         &transcodingParam, fre, fim, lpcGains,
                         kIsacUpperBand12, err);
  }
  if (err < 0) {
    return err;
  }
  /* Complete arithmetic coding. */
  return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
}






/* This function is used to create a new bit-stream with new BWE.
   The same data as previously encoded with the function WebRtcIsac_Encoder().
   The data needed is taken from the structure, where it was stored
   when calling the encoder. */

int WebRtcIsac_EncodeStoredDataLb(const IsacSaveEncoderData* ISACSavedEnc_obj,
                                  Bitstr* ISACBitStr_obj, int BWnumber,
                                  float scale) {
  int ii;
  int status;
  int BWno = BWnumber;

  const uint16_t* WebRtcIsac_kQPitchGainCdf_ptr[1];
  const uint16_t** cdf;

  double tmpLPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * 2];
  double tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * 2];
  int tmpLPCindex_g[12 * 2];
  int16_t tmp_fre[FRAMESAMPLES], tmp_fim[FRAMESAMPLES];
  const int kModel = 0;

  /* Sanity Check - possible values for BWnumber is 0 - 23. */
  if ((BWnumber < 0) || (BWnumber > 23)) {
    return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
  }

  /* Reset bit-stream. */
  WebRtcIsac_ResetBitstream(ISACBitStr_obj);

  /* Encode frame length */
  status = WebRtcIsac_EncodeFrameLen(ISACSavedEnc_obj->framelength,
                                     ISACBitStr_obj);
  if (status < 0) {
    /* Wrong frame size. */
    return status;
  }

  /* Transcoding */
  if ((scale > 0.0) && (scale < 1.0)) {
    /* Compensate LPC gain. */
    for (ii = 0;
        ii < ((ORDERLO + 1)* SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
        ii++) {
      tmpLPCcoeffs_lo[ii] = scale *  ISACSavedEnc_obj->LPCcoeffs_lo[ii];
    }
    for (ii = 0;
        ii < ((ORDERHI + 1) * SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
        ii++) {
      tmpLPCcoeffs_hi[ii] = scale *  ISACSavedEnc_obj->LPCcoeffs_hi[ii];
    }
    /* Scale DFT. */
    for (ii = 0;
        ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
        ii++) {
      tmp_fre[ii] = (int16_t)((scale) * (float)ISACSavedEnc_obj->fre[ii]);
      tmp_fim[ii] = (int16_t)((scale) * (float)ISACSavedEnc_obj->fim[ii]);
    }
  } else {
    for (ii = 0;
        ii < (KLT_ORDER_GAIN * (1 + ISACSavedEnc_obj->startIdx));
        ii++) {
      tmpLPCindex_g[ii] =  ISACSavedEnc_obj->LPCindex_g[ii];
    }
    for (ii = 0;
        ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
        ii++) {
      tmp_fre[ii] = ISACSavedEnc_obj->fre[ii];
      tmp_fim[ii] = ISACSavedEnc_obj->fim[ii];
    }
  }

  /* Encode bandwidth estimate. */
  WebRtcIsac_EncodeReceiveBw(&BWno, ISACBitStr_obj);

  /* Loop over number of 30 msec */
  for (ii = 0; ii <= ISACSavedEnc_obj->startIdx; ii++) {
    /* Encode pitch gains. */
    *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
    WebRtcIsac_EncHistMulti(ISACBitStr_obj,
                            &ISACSavedEnc_obj->pitchGain_index[ii],
                            WebRtcIsac_kQPitchGainCdf_ptr, 1);

    /* Entropy coding of quantization pitch lags */
    /* Voicing classification. */
    if (ISACSavedEnc_obj->meanGain[ii] < 0.2) {
      cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
    } else if (ISACSavedEnc_obj->meanGain[ii] < 0.4) {
      cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
    } else {
      cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
    }
    WebRtcIsac_EncHistMulti(ISACBitStr_obj,
                            &ISACSavedEnc_obj->pitchIndex[PITCH_SUBFRAMES * ii],
                            cdf, PITCH_SUBFRAMES);

    /* LPC */
    /* Only one model exists. The entropy coding is done only for backward
     * compatibility. */
    WebRtcIsac_EncHistMulti(ISACBitStr_obj, &kModel,
                            WebRtcIsac_kQKltModelCdfPtr, 1);
    /* Entropy coding of quantization indices - LPC shape only. */
    WebRtcIsac_EncHistMulti(ISACBitStr_obj,
                            &ISACSavedEnc_obj->LPCindex_s[KLT_ORDER_SHAPE * ii],
                            WebRtcIsac_kQKltCdfPtrShape,
                            KLT_ORDER_SHAPE);

    /* If transcoding, get new LPC gain indices */
    if (scale < 1.0) {
      WebRtcIsac_TranscodeLPCCoef(
          &tmpLPCcoeffs_lo[(ORDERLO + 1) * SUBFRAMES * ii],
          &tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * ii],
          &tmpLPCindex_g[KLT_ORDER_GAIN * ii]);
    }

    /* Entropy coding of quantization indices - LPC gain. */
    WebRtcIsac_EncHistMulti(ISACBitStr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN * ii],
                            WebRtcIsac_kQKltCdfPtrGain, KLT_ORDER_GAIN);

    /* Quantization and loss-less coding. */
    status = WebRtcIsac_EncodeSpec(&tmp_fre[ii * FRAMESAMPLES_HALF],
                                   &tmp_fim[ii * FRAMESAMPLES_HALF],
                                   ISACSavedEnc_obj->AvgPitchGain[ii],
                                   kIsacLowerBand, ISACBitStr_obj);
    if (status < 0) {
      return status;
    }
  }
  /* Complete arithmetic coding. */
  return WebRtcIsac_EncTerminate(ISACBitStr_obj);
}


int WebRtcIsac_EncodeStoredDataUb(
    const ISACUBSaveEncDataStruct* ISACSavedEnc_obj,
    Bitstr* bitStream,
    int32_t jitterInfo,
    float scale,
    enum ISACBandwidth bandwidth) {
  int n;
  int err;
  double lpcGain[SUBFRAMES];
  int16_t realFFT[FRAMESAMPLES_HALF];
  int16_t imagFFT[FRAMESAMPLES_HALF];
  const uint16_t** shape_cdf;
  int shape_len;
  const int16_t kAveragePitchGain = 0.0;
  enum ISACBand band;
  /* Reset bitstream. */
  WebRtcIsac_ResetBitstream(bitStream);

  /* Encode jitter index. */
  WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream);

  err = WebRtcIsac_EncodeBandwidth(bandwidth, bitStream);
  if (err < 0) {
    return err;
  }

  /* Encode LPC-shape. */
  if (bandwidth == isac12kHz) {
    shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb12;
    shape_len = UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME;
    band = kIsacUpperBand12;
  } else {
    shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb16;
    shape_len = UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME;
    band = kIsacUpperBand16;
  }
  WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape,
                          shape_cdf, shape_len);

  if ((scale <= 0.0) || (scale >= 1.0)) {
    /* We only consider scales between zero and one. */
    WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex,
                            WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
    if (bandwidth == isac16kHz) {
      /* Store gain indices of the second half. */
      WebRtcIsac_EncHistMulti(bitStream,
                              &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES],
                              WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
    }
    /* Store FFT coefficients. */
    err = WebRtcIsac_EncodeSpec(ISACSavedEnc_obj->realFFT,
                                ISACSavedEnc_obj->imagFFT, kAveragePitchGain,
                                band, bitStream);
  } else {
    /* Scale LPC gain and FFT coefficients. */
    for (n = 0; n < SUBFRAMES; n++) {
      lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n];
    }
    /* Store LPC gains. */
    WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);

    if (bandwidth == isac16kHz) {
      /* Scale and code the gains of the second half of the frame, if 16kHz. */
      for (n = 0; n < SUBFRAMES; n++) {
        lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES];
      }
      WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
    }

    for (n = 0; n < FRAMESAMPLES_HALF; n++) {
      realFFT[n] = (int16_t)(scale * (float)ISACSavedEnc_obj->realFFT[n] +
          0.5f);
      imagFFT[n] = (int16_t)(scale * (float)ISACSavedEnc_obj->imagFFT[n] +
          0.5f);
    }
    /* Store FFT coefficients. */
    err = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain,
                                band, bitStream);
  }
  if (err < 0) {
    /* Error happened while encoding FFT coefficients. */
    return err;
  }

  /* Complete arithmetic coding. */
  return WebRtcIsac_EncTerminate(bitStream);
}

int16_t WebRtcIsac_GetRedPayloadUb(
    const ISACUBSaveEncDataStruct* ISACSavedEncObj,
    Bitstr*                        bitStreamObj,
    enum ISACBandwidth             bandwidth) {
  int n;
  int16_t status;
  int16_t realFFT[FRAMESAMPLES_HALF];
  int16_t imagFFT[FRAMESAMPLES_HALF];
  enum ISACBand band;
  const int16_t kAveragePitchGain = 0.0;
  /* Store bit-stream object. */
  memcpy(bitStreamObj, &ISACSavedEncObj->bitStreamObj, sizeof(Bitstr));

  /* Scale FFT coefficients. */
  for (n = 0; n < FRAMESAMPLES_HALF; n++) {
    realFFT[n] = (int16_t)((float)ISACSavedEncObj->realFFT[n] *
        RCU_TRANSCODING_SCALE_UB + 0.5);
    imagFFT[n] = (int16_t)((float)ISACSavedEncObj->imagFFT[n] *
        RCU_TRANSCODING_SCALE_UB + 0.5);
  }

  band = (bandwidth == isac12kHz) ? kIsacUpperBand12 : kIsacUpperBand16;
  status = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, band,
                                 bitStreamObj);
  if (status < 0) {
    return status;
  } else {
    /* Terminate entropy coding */
    return WebRtcIsac_EncTerminate(bitStreamObj);
  }
}
