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

/*
 * encode.c
 *
 * Encoding function for the iSAC coder.
 *
 */

#include "webrtc/rtc_base/checks.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h"

#include <stdio.h>

#include "webrtc/modules/audio_coding/codecs/isac/fix/source/arith_routins.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h"


int WebRtcIsacfix_EncodeImpl(int16_t      *in,
                             IsacFixEncoderInstance  *ISACenc_obj,
                             BwEstimatorstr      *bw_estimatordata,
                             int16_t         CodingMode)
{
  int16_t stream_length = 0;
  int16_t usefulstr_len = 0;
  int k;
  int16_t BWno;

  int16_t lofilt_coefQ15[(ORDERLO)*SUBFRAMES];
  int16_t hifilt_coefQ15[(ORDERHI)*SUBFRAMES];
  int32_t gain_lo_hiQ17[2*SUBFRAMES];

  int16_t LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD];
  int16_t LP16a[FRAMESAMPLES/2 + QLOOKAHEAD];
  int16_t HP16a[FRAMESAMPLES/2 + QLOOKAHEAD];

  int16_t PitchLags_Q7[PITCH_SUBFRAMES];
  int16_t PitchGains_Q12[PITCH_SUBFRAMES];
  int16_t AvgPitchGain_Q12;

  int16_t frame_mode; /* 0 for 30ms, 1 for 60ms */
  int16_t processed_samples;
  int status;

  int32_t bits_gainsQ11;
  int16_t MinBytes;
  int16_t bmodel;

  transcode_obj transcodingParam;
  int16_t payloadLimitBytes;
  int16_t arithLenBeforeEncodingDFT;
  int16_t iterCntr;

  /* copy new frame length and bottle neck rate only for the first 10 ms data */
  if (ISACenc_obj->buffer_index == 0) {
    /* set the framelength for the next packet */
    ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength;
  }

  frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms)  */
  processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */

  /* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */
  /**************************************************************************************/
  /* fill the buffer with 10ms input data */
  for(k=0; k<FRAMESAMPLES_10ms; k++) {
    ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k];
  }
  /* if buffersize is not equal to current framesize, and end of file is not reached yet, */
  /* increase index and go back to main to get more speech samples */
  if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) {
    ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms;
    return 0;
  }
  /* if buffer reached the right size, reset index and continue with encoding the frame */
  ISACenc_obj->buffer_index = 0;

  /* end of buffer function */
  /**************************/

  /* encoding */
  /************/

  if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 )
  {
    /* reset bitstream */
    ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
    ISACenc_obj->bitstr_obj.streamval = 0;
    ISACenc_obj->bitstr_obj.stream_index = 0;
    ISACenc_obj->bitstr_obj.full = 1;

    if (CodingMode == 0) {
      ISACenc_obj->BottleNeck =  WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata);
      ISACenc_obj->MaxDelay =  WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata);
    }
    if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
      ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
                                                                     ISACenc_obj->current_framesamples);
    }

    // multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT
    // 901/1024 is 0.87988281250000
    ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr(
        (int16_t)(ISACenc_obj->BottleNeck * 901 >> 10),
        ISACenc_obj->current_framesamples);

    /* encode frame length */
    status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj);
    if (status < 0)
    {
      /* Wrong frame size */
      if (frame_mode == 1 && ISACenc_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.
        ISACenc_obj->frame_nb = 0;
      }
      return status;
    }

    /* Save framelength for multiple packets memory */
    if (ISACenc_obj->SaveEnc_ptr != NULL) {
      (ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples;
    }

    /* bandwidth estimation and coding */
    BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata);
    status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
    if (status < 0)
    {
      if (frame_mode == 1 && ISACenc_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.
        ISACenc_obj->frame_nb = 0;
      }
      return status;
    }
  }

  /* split signal in two bands */
  WebRtcIsacfix_SplitAndFilter1(ISACenc_obj->data_buffer_fix, LP16a, HP16a, &ISACenc_obj->prefiltbankstr_obj );

  /* estimate pitch parameters and pitch-filter lookahead signal */
  WebRtcIsacfix_PitchAnalysis(LP16a+QLOOKAHEAD, LPandHP,
                              &ISACenc_obj->pitchanalysisstr_obj,  PitchLags_Q7, PitchGains_Q12); /* LPandHP = LP_lookahead_pfQ0, */

  /* Set where to store data in multiple packets memory */
  if (ISACenc_obj->SaveEnc_ptr != NULL) {
    if (frame_mode == 0 || ISACenc_obj->frame_nb == 0)
    {
      (ISACenc_obj->SaveEnc_ptr)->startIdx = 0;
    }
    else
    {
      (ISACenc_obj->SaveEnc_ptr)->startIdx = 1;
    }
  }

  /* quantize & encode pitch parameters */
  status = WebRtcIsacfix_EncodePitchGain(PitchGains_Q12, &ISACenc_obj->bitstr_obj,  ISACenc_obj->SaveEnc_ptr);
  if (status < 0)
  {
    if (frame_mode == 1 && ISACenc_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.
      ISACenc_obj->frame_nb = 0;
    }
    return status;
  }
  status = WebRtcIsacfix_EncodePitchLag(PitchLags_Q7 , PitchGains_Q12, &ISACenc_obj->bitstr_obj,  ISACenc_obj->SaveEnc_ptr);
  if (status < 0)
  {
    if (frame_mode == 1 && ISACenc_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.
      ISACenc_obj->frame_nb = 0;
    }
    return status;
  }
  AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
      PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;

  /* find coefficients for perceptual pre-filters */
  WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj,
                           ISACenc_obj->s2nr, PitchGains_Q12,
                           gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15); /*LPandHP = LP_lookahead_pfQ0*/

  // record LPC Gains for possible bit-rate reduction
  for(k = 0; k < KLT_ORDER_GAIN; k++)
  {
    transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
  }

  /* code LPC model and shape - gains not quantized yet */
  status = WebRtcIsacfix_EncodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
                                   &bmodel, &bits_gainsQ11, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr, &transcodingParam);
  if (status < 0)
  {
    if (frame_mode == 1 && ISACenc_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.
      ISACenc_obj->frame_nb = 0;
    }
    return status;
  }
  arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);

  /* low-band filtering */
  WebRtcIsacfix_NormLatticeFilterMa(ORDERLO, ISACenc_obj->maskfiltstr_obj.PreStateLoGQ15,
                                    LP16a, lofilt_coefQ15, gain_lo_hiQ17, 0, LPandHP);/* LPandHP = LP16b */

  /* pitch filter */
  WebRtcIsacfix_PitchFilter(LPandHP, LP16a, &ISACenc_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 1);/* LPandHP = LP16b */

  /* high-band filtering */
  WebRtcIsacfix_NormLatticeFilterMa(ORDERHI, ISACenc_obj->maskfiltstr_obj.PreStateHiGQ15,
                                    HP16a, hifilt_coefQ15, gain_lo_hiQ17, 1, LPandHP);/*LPandHP = HP16b*/

  /* transform */
  WebRtcIsacfix_Time2Spec(LP16a, LPandHP, LP16a, LPandHP); /*LPandHP = HP16b*/

  /* Save data for multiple packets memory */
  if (ISACenc_obj->SaveEnc_ptr != NULL) {
    for (k = 0; k < FRAMESAMPLES_HALF; k++) {
      (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
      (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
    }
    (ISACenc_obj->SaveEnc_ptr)->AvgPitchGain[(ISACenc_obj->SaveEnc_ptr)->startIdx] = AvgPitchGain_Q12;
  }

  /* quantization and lossless coding */
  status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
  if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
  {
    if (frame_mode == 1 && ISACenc_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.
      ISACenc_obj->frame_nb = 0;
    }
    return status;
  }

  if((frame_mode == 1) && (ISACenc_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 = ISACenc_obj->payloadLimitBytes60 >> 1;
  }
  else if (frame_mode == 0)
  {
    // it is a 30ms frame
    payloadLimitBytes = (ISACenc_obj->payloadLimitBytes30) - 3;
  }
  else
  {
    // this is the second half of a 60ms frame.
    payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 - 3; // subract 3 because termination process may add 3 bytes
  }

  iterCntr = 0;
  while((((ISACenc_obj->bitstr_obj.stream_index) << 1) > payloadLimitBytes) ||
        (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH))
  {
    int16_t arithLenDFTByte;
    int16_t bytesLeftQ5;
    int16_t ratioQ5[8] = {0, 6, 9, 12, 16, 19, 22, 25};

    // According to experiments on TIMIT the following is proper for audio, but it is not agressive enough for tonal inputs
    // such as DTMF, sweep-sine, ...
    //
    // (0.55 - (0.8 - ratio[i]/32) * 5 / 6) * 2^14
    // int16_t scaleQ14[8] = {0, 648, 1928, 3208, 4915, 6195, 7475, 8755};


    // This is a supper-agressive scaling passed the tests (tonal inputs) tone with one iteration for payload limit
    // of 120 (32kbps bottleneck), number of frames needed a rate-reduction was 58403
    //
    int16_t scaleQ14[8] = {0, 348, 828, 1408, 2015, 3195, 3500, 3500};
    int16_t idx;

    if(iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION)
    {
      // We were not able to limit the payload size

      if((frame_mode == 1) && (ISACenc_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 togetehr we won't exceed
        // the limit.
        ISACenc_obj->frame_nb = 1;
        return 0;
      }
      else if((frame_mode == 1) && (ISACenc_obj->frame_nb == 1))
      {
        ISACenc_obj->frame_nb = 0;
      }

      if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)
      {
        return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
      }
      else
      {
        return status;
      }
    }
    if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)
    {
      arithLenDFTByte = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full) - arithLenBeforeEncodingDFT;
      bytesLeftQ5 = (payloadLimitBytes - arithLenBeforeEncodingDFT) << 5;

      // bytesLeft / arithLenDFTBytes indicates how much scaling is required a rough estimate (agressive)
      // scale = 0.55 - (0.8 - bytesLeft / arithLenDFTBytes) * 5 / 6
      // bytesLeft / arithLenDFTBytes below 0.2 will have a scale of zero and above 0.8 are treated as 0.8
      // to avoid division we do more simplification.
      //
      // values of (bytesLeft / arithLenDFTBytes)*32 between ratioQ5[i] and ratioQ5[i+1] are rounded to ratioQ5[i]
      // and the corresponding scale is chosen

      // we compare bytesLeftQ5 with ratioQ5[]*arithLenDFTByte;
      idx = 4;
      idx += (bytesLeftQ5 >= ratioQ5[idx] * arithLenDFTByte) ? 2 : -2;
      idx += (bytesLeftQ5 >= ratioQ5[idx] * arithLenDFTByte) ? 1 : -1;
      idx += (bytesLeftQ5 >= ratioQ5[idx] * arithLenDFTByte) ? 0 : -1;
    }
    else
    {
      // we are here because the bit-stream did not fit into the buffer, in this case, the stream_index is not
      // trustable, especially if the is the first 30ms of a packet. Thereforem, we will go for the most agressive
      // case.
      idx = 0;
    }
    // scale FFT coefficients to reduce the bit-rate
    for(k = 0; k < FRAMESAMPLES_HALF; k++)
    {
      LP16a[k] = (int16_t)(LP16a[k] * scaleQ14[idx] >> 14);
      LPandHP[k] = (int16_t)(LPandHP[k] * scaleQ14[idx] >> 14);
    }

    // Save data for multiple packets memory
    if (ISACenc_obj->SaveEnc_ptr != NULL)
    {
      for(k = 0; k < FRAMESAMPLES_HALF; k++)
      {
        (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
        (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
      }
    }

    // scale the unquantized LPC gains and save the scaled version for the future use
    for(k = 0; k < KLT_ORDER_GAIN; k++)
    {
      gain_lo_hiQ17[k] = WEBRTC_SPL_MUL_16_32_RSFT14(scaleQ14[idx], transcodingParam.lpcGains[k]);//transcodingParam.lpcGains[k]; //
      transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
    }

    // reset the bit-stream object to the state which it had before encoding LPC Gains
    ISACenc_obj->bitstr_obj.full = transcodingParam.full;
    ISACenc_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
    ISACenc_obj->bitstr_obj.streamval = transcodingParam.streamval;
    ISACenc_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
    ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index-1] = transcodingParam.beforeLastWord;
    ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index] = transcodingParam.lastWord;


    // quantize and encode LPC gain
    WebRtcIsacfix_EstCodeLpcGain(gain_lo_hiQ17, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr);
    arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);
    status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
    if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
    {
      if (frame_mode == 1 && ISACenc_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.
        ISACenc_obj->frame_nb = 0;
      }
      return status;
    }
    iterCntr++;
  }

  if (frame_mode == 1 && ISACenc_obj->frame_nb == 0)
    /* i.e. 60 ms framesize and just processed the first 30ms, */
    /* go back to main function to buffer the other 30ms speech frame */
  {
    ISACenc_obj->frame_nb = 1;
    return 0;
  }
  else if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
  {
    ISACenc_obj->frame_nb = 0;
    /* also update the framelength for next packet, in Adaptive mode only */
    if (CodingMode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
      ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
                                                                     ISACenc_obj->current_framesamples);
    }
  }


  /* complete arithmetic coding */
  stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj);
  /* can this be negative? */

  if(CodingMode == 0)
  {

    /* update rate model and get minimum number of bytes in this packet */
    MinBytes = WebRtcIsacfix_GetMinBytes(&ISACenc_obj->rate_data_obj, (int16_t) stream_length,
                                         ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck, ISACenc_obj->MaxDelay);

    /* if bitstream is too short, add garbage at the end */

    /* Store length of coded data */
    usefulstr_len = stream_length;

    /* Make sure MinBytes does not exceed packet size limit */
    if ((ISACenc_obj->frame_nb == 0) && (MinBytes > ISACenc_obj->payloadLimitBytes30)) {
      MinBytes = ISACenc_obj->payloadLimitBytes30;
    } else if ((ISACenc_obj->frame_nb == 1) && (MinBytes > ISACenc_obj->payloadLimitBytes60)) {
      MinBytes = ISACenc_obj->payloadLimitBytes60;
    }

    /* 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 lenght we can signal using 8 bits. */
    if( MinBytes > usefulstr_len + 255 ) {
      MinBytes = usefulstr_len + 255;
    }

    /* Save data for creation of multiple bitstreams */
    if (ISACenc_obj->SaveEnc_ptr != NULL) {
      (ISACenc_obj->SaveEnc_ptr)->minBytes = MinBytes;
    }

    while (stream_length < MinBytes)
    {
      RTC_DCHECK_GE(stream_length, 0);
      if (stream_length & 0x0001){
        ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
        ISACenc_obj->bitstr_obj.stream[stream_length / 2] |=
            (uint16_t)(ISACenc_obj->bitstr_seed & 0xFF);
      } else {
        ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
        ISACenc_obj->bitstr_obj.stream[stream_length / 2] =
            ((uint16_t)ISACenc_obj->bitstr_seed << 8);
      }
      stream_length++;
    }

    /* to get the real stream_length, without garbage */
    if (usefulstr_len & 0x0001) {
      ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0xFF00;
      ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += (MinBytes - usefulstr_len) & 0x00FF;
    }
    else {
      ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0x00FF;
      ISACenc_obj->bitstr_obj.stream[usefulstr_len >> 1] +=
          ((uint16_t)((MinBytes - usefulstr_len) & 0x00FF) << 8);
    }
  }
  else
  {
    /* update rate model */
    WebRtcIsacfix_UpdateRateModel(&ISACenc_obj->rate_data_obj, (int16_t) stream_length,
                                  ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck);
  }
  return stream_length;
}

/* This function is used to create a new bitstream with new BWE.
   The same data as previously encoded with the fucntion WebRtcIsacfix_EncodeImpl()
   is used. The data needed is taken from the struct, where it was stored
   when calling the encoder. */
int WebRtcIsacfix_EncodeStoredData(IsacFixEncoderInstance  *ISACenc_obj,
                                   int     BWnumber,
                                   float              scale)
{
  int ii;
  int status;
  int16_t BWno = (int16_t)BWnumber;
  int stream_length = 0;

  int16_t model;
  const uint16_t *Q_PitchGain_cdf_ptr[1];
  const uint16_t **cdf;
  const IsacSaveEncoderData *SaveEnc_str;
  int32_t tmpLPCcoeffs_g[KLT_ORDER_GAIN<<1];
  int16_t tmpLPCindex_g[KLT_ORDER_GAIN<<1];
  int16_t tmp_fre[FRAMESAMPLES];
  int16_t tmp_fim[FRAMESAMPLES];

  SaveEnc_str = ISACenc_obj->SaveEnc_ptr;

  /* Check if SaveEnc memory exists */
  if (SaveEnc_str == NULL) {
    return (-1);
  }

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

  /* reset bitstream */
  ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
  ISACenc_obj->bitstr_obj.streamval = 0;
  ISACenc_obj->bitstr_obj.stream_index = 0;
  ISACenc_obj->bitstr_obj.full = 1;

  /* encode frame length */
  status = WebRtcIsacfix_EncodeFrameLen(SaveEnc_str->framelength, &ISACenc_obj->bitstr_obj);
  if (status < 0) {
    /* Wrong frame size */
    return status;
  }

  /* encode bandwidth estimate */
  status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
  if (status < 0) {
    return status;
  }

  /* Transcoding                                                 */
  /* If scale < 1, rescale data to produce lower bitrate signal  */
  if ((0.0 < scale) && (scale < 1.0)) {
    /* Compensate LPC gain */
    for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) {
      tmpLPCcoeffs_g[ii] = (int32_t) ((scale) * (float) SaveEnc_str->LPCcoeffs_g[ii]);
    }

    /* Scale DFT */
    for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
      tmp_fre[ii] = (int16_t) ((scale) * (float) SaveEnc_str->fre[ii]) ;
      tmp_fim[ii] = (int16_t) ((scale) * (float) SaveEnc_str->fim[ii]) ;
    }
  } else {
    for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) {
      tmpLPCindex_g[ii] =  SaveEnc_str->LPCindex_g[ii];
    }

    for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
      tmp_fre[ii] = SaveEnc_str->fre[ii];
      tmp_fim[ii] = SaveEnc_str->fim[ii];
    }
  }

  /* Loop over number of 30 msec */
  for (ii = 0; ii <= SaveEnc_str->startIdx; ii++)
  {

    /* encode pitch gains */
    *Q_PitchGain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->pitchGain_index[ii],
                                       Q_PitchGain_cdf_ptr, 1);
    if (status < 0) {
      return status;
    }

    /* entropy coding of quantization pitch lags */
    /* voicing classificiation */
    if (SaveEnc_str->meanGain[ii] <= 819) {
      cdf = WebRtcIsacfix_kPitchLagPtrLo;
    } else if (SaveEnc_str->meanGain[ii] <= 1638) {
      cdf = WebRtcIsacfix_kPitchLagPtrMid;
    } else {
      cdf = WebRtcIsacfix_kPitchLagPtrHi;
    }
    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj,
                                       &SaveEnc_str->pitchIndex[PITCH_SUBFRAMES*ii], cdf, PITCH_SUBFRAMES);
    if (status < 0) {
      return status;
    }

    /* LPC */
    /* entropy coding of model number */
    model = 0;
    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj,  &model,
                                       WebRtcIsacfix_kModelCdfPtr, 1);
    if (status < 0) {
      return status;
    }

    /* entropy coding of quantization indices - LPC shape only */
    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->LPCindex_s[KLT_ORDER_SHAPE*ii],
                                       WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE);
    if (status < 0) {
      return status;
    }

    /* If transcoding, get new LPC gain indices */
    if (scale < 1.0) {
      WebRtcIsacfix_TranscodeLpcCoef(&tmpLPCcoeffs_g[KLT_ORDER_GAIN*ii], &tmpLPCindex_g[KLT_ORDER_GAIN*ii]);
    }

    /* entropy coding of quantization indices - LPC gain */
    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN*ii],
                                       WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
    if (status < 0) {
      return status;
    }

    /* quantization and lossless coding */
    status = WebRtcIsacfix_EncodeSpec(&tmp_fre[ii*FRAMESAMPLES_HALF], &tmp_fim[ii*FRAMESAMPLES_HALF],
                                      &ISACenc_obj->bitstr_obj, SaveEnc_str->AvgPitchGain[ii]);
    if (status < 0) {
      return status;
    }
  }

  /* complete arithmetic coding */
  stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj);

  return stream_length;
}
