/*
 *  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 "arith_routins.h"
#include "bandwidth_estimator.h"
#include "codec.h"
#include "pitch_gain_tables.h"
#include "pitch_lag_tables.h"
#include "entropy_coding.h"
#include "lpc_tables.h"
#include "lpc_masking_model.h"
#include "pitch_estimator.h"
#include "structs.h"
#include <stdio.h>


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

  WebRtc_Word16 lofilt_coefQ15[(ORDERLO)*SUBFRAMES];
  WebRtc_Word16 hifilt_coefQ15[(ORDERHI)*SUBFRAMES];
  WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES];

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

  WebRtc_Word16 PitchLags_Q7[PITCH_SUBFRAMES];
  WebRtc_Word16 PitchGains_Q12[PITCH_SUBFRAMES];
  WebRtc_Word16 AvgPitchGain_Q12;

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

  WebRtc_Word32 bits_gainsQ11;
  WebRtc_Word16 MinBytes;
  WebRtc_Word16 bmodel;

  transcode_obj transcodingParam;
  WebRtc_Word16 payloadLimitBytes;
  WebRtc_Word16 arithLenBeforeEncodingDFT;
  WebRtc_Word16 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((WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(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 = WEBRTC_SPL_RSHIFT_W32(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))
  {
    WebRtc_Word16 arithLenDFTByte;
    WebRtc_Word16 bytesLeftQ5;
    WebRtc_Word16 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
    // WebRtc_Word16 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
    //
    WebRtc_Word16 scaleQ14[8] = {0, 348, 828, 1408, 2015, 3195, 3500, 3500};
    WebRtc_Word16 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 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 2:-2;
      idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 1:-1;
      idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(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] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LP16a[k], scaleQ14[idx], 14);
      LPandHP[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(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, (WebRtc_Word16) 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)
    {
      if (stream_length & 0x0001){
        ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
        ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] |= (WebRtc_UWord16)(ISACenc_obj->bitstr_seed & 0xFF);
      } else {
        ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
        ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] = WEBRTC_SPL_LSHIFT_U16(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] += WEBRTC_SPL_LSHIFT_U16((MinBytes - usefulstr_len) & 0x00FF, 8);
    }
  }
  else
  {
    /* update rate model */
    WebRtcIsacfix_UpdateRateModel(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) 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(ISACFIX_EncInst_t  *ISACenc_obj,
                                   int     BWnumber,
                                   float              scale,
                                   WebRtc_Word16        CodingMode)
{
  int ii;
  int status;
  WebRtc_Word16 BWno = BWnumber;
  int stream_length = 0;
  int usefulstr_len;

  WebRtc_Word16 model;
  const WebRtc_UWord16 *Q_PitchGain_cdf_ptr[1];
  const WebRtc_UWord16 **cdf;
  const ISAC_SaveEncData_t *SaveEnc_str;
  WebRtc_Word32 tmpLPCcoeffs_g[KLT_ORDER_GAIN<<1];
  WebRtc_Word16 tmpLPCindex_g[KLT_ORDER_GAIN<<1];
  WebRtc_Word16 tmp_fre[FRAMESAMPLES];
  WebRtc_Word16 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] = (WebRtc_Word32) ((scale) * (float) SaveEnc_str->LPCcoeffs_g[ii]);
    }

    /* Scale DFT */
    for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
      tmp_fre[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fre[ii]) ;
      tmp_fim[ii] = (WebRtc_Word16) ((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;
}
