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

/*
 * BwEstimator.c
 *
 * This file contains the code for the Bandwidth Estimator designed
 * for iSAC.
 *
 */

#include "bandwidth_estimator.h"
#include "settings.h"
#include "isac.h"

#include <math.h>

/* array of quantization levels for bottle neck info; Matlab code: */
/* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */
static const float kQRateTableWb[12] =
{
  10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
  18859.8f, 20963.3f, 23301.4f, 25900.3f, 28789.0f, 32000.0f};


static const float kQRateTableSwb[24] =
{
  10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
  18859.8f, 20963.3f, 23153.1f, 25342.9f, 27532.7f, 29722.5f,
  31912.3f, 34102.1f, 36291.9f, 38481.7f, 40671.4f, 42861.2f,
  45051.0f, 47240.8f, 49430.6f, 51620.4f, 53810.2f, 56000.0f,
};




WebRtc_Word32 WebRtcIsac_InitBandwidthEstimator(
    BwEstimatorstr*              bwest_str,
    enum IsacSamplingRate encoderSampRate,
    enum IsacSamplingRate decoderSampRate)
{
  switch(encoderSampRate)
  {
    case kIsacWideband:
      {
        bwest_str->send_bw_avg       = INIT_BN_EST_WB;
        break;
      }
    case kIsacSuperWideband:
      {
        bwest_str->send_bw_avg       = INIT_BN_EST_SWB;
        break;
      }
  }

  switch(decoderSampRate)
  {
    case kIsacWideband:
      {
        bwest_str->prev_frame_length = INIT_FRAME_LEN_WB;
        bwest_str->rec_bw_inv        = 1.0f /
            (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
        bwest_str->rec_bw            = (WebRtc_Word32)INIT_BN_EST_WB;
        bwest_str->rec_bw_avg_Q      = INIT_BN_EST_WB;
        bwest_str->rec_bw_avg        = INIT_BN_EST_WB + INIT_HDR_RATE_WB;
        bwest_str->rec_header_rate   = INIT_HDR_RATE_WB;
        break;
      }
    case kIsacSuperWideband:
      {
        bwest_str->prev_frame_length = INIT_FRAME_LEN_SWB;
        bwest_str->rec_bw_inv        = 1.0f /
            (INIT_BN_EST_SWB + INIT_HDR_RATE_SWB);
        bwest_str->rec_bw            = (WebRtc_Word32)INIT_BN_EST_SWB;
        bwest_str->rec_bw_avg_Q      = INIT_BN_EST_SWB;
        bwest_str->rec_bw_avg        = INIT_BN_EST_SWB + INIT_HDR_RATE_SWB;
        bwest_str->rec_header_rate   = INIT_HDR_RATE_SWB;
        break;
      }
  }

  bwest_str->prev_rec_rtp_number       = 0;
  bwest_str->prev_rec_arr_ts           = 0;
  bwest_str->prev_rec_send_ts          = 0;
  bwest_str->prev_rec_rtp_rate         = 1.0f;
  bwest_str->last_update_ts            = 0;
  bwest_str->last_reduction_ts         = 0;
  bwest_str->count_tot_updates_rec     = -9;
  bwest_str->rec_jitter                = 10.0f;
  bwest_str->rec_jitter_short_term     = 0.0f;
  bwest_str->rec_jitter_short_term_abs = 5.0f;
  bwest_str->rec_max_delay             = 10.0f;
  bwest_str->rec_max_delay_avg_Q       = 10.0f;
  bwest_str->num_pkts_rec              = 0;

  bwest_str->send_max_delay_avg        = 10.0f;

  bwest_str->hsn_detect_rec = 0;

  bwest_str->num_consec_rec_pkts_over_30k = 0;

  bwest_str->hsn_detect_snd = 0;

  bwest_str->num_consec_snt_pkts_over_30k = 0;

  bwest_str->in_wait_period = 0;

  bwest_str->change_to_WB = 0;

  bwest_str->numConsecLatePkts = 0;
  bwest_str->consecLatency = 0;
  bwest_str->inWaitLatePkts = 0;
  bwest_str->senderTimestamp = 0;
  bwest_str->receiverTimestamp = 0;
  return 0;
}

/* This function updates both bottle neck rates                                                      */
/* Parameters:                                                                                       */
/* rtp_number    - value from RTP packet, from NetEq                                                 */
/* frame length  - length of signal frame in ms, from iSAC decoder                                   */
/* send_ts       - value in RTP header giving send time in samples                                     */
/* arr_ts        - value given by timeGetTime() time of arrival in samples of packet from NetEq      */
/* pksize        - size of packet in bytes, from NetEq                                               */
/* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
/* returns 0 if everything went fine, -1 otherwise                                                   */
WebRtc_Word16 WebRtcIsac_UpdateBandwidthEstimator(
    BwEstimatorstr *bwest_str,
    const WebRtc_UWord16 rtp_number,
    const WebRtc_Word32  frame_length,
    const WebRtc_UWord32 send_ts,
    const WebRtc_UWord32 arr_ts,
    const WebRtc_Word32  pksize
    /*,    const WebRtc_UWord16 Index*/)
{
  float weight = 0.0f;
  float curr_bw_inv = 0.0f;
  float rec_rtp_rate;
  float t_diff_proj;
  float arr_ts_diff;
  float send_ts_diff;
  float arr_time_noise;
  float arr_time_noise_abs;

  float delay_correction_factor = 1;
  float late_diff = 0.0f;
  int immediate_set = 0;
  int num_pkts_expected;


  // We have to adjust the header-rate if the first packet has a
  // frame-size different than the initialized value.
  if ( frame_length != bwest_str->prev_frame_length )
  {
    bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
        1000.0f / (float)frame_length;     /* bits/s */
  }

  /* UPDATE ESTIMATES ON THIS SIDE */
  /* compute far-side transmission rate */
  rec_rtp_rate = ((float)pksize * 8.0f * 1000.0f / (float)frame_length) +
      bwest_str->rec_header_rate;
  // rec_rtp_rate packet bits/s + header bits/s

  /* check for timer wrap-around */
  if (arr_ts < bwest_str->prev_rec_arr_ts)
  {
    bwest_str->prev_rec_arr_ts   = arr_ts;
    bwest_str->last_update_ts    = arr_ts;
    bwest_str->last_reduction_ts = arr_ts + 3*FS;
    bwest_str->num_pkts_rec      = 0;

    /* store frame length */
    bwest_str->prev_frame_length = frame_length;

    /* store far-side transmission rate */
    bwest_str->prev_rec_rtp_rate = rec_rtp_rate;

    /* store far-side RTP time stamp */
    bwest_str->prev_rec_rtp_number = rtp_number;

    return 0;
  }

  bwest_str->num_pkts_rec++;

  /* check that it's not one of the first 9 packets */
  if ( bwest_str->count_tot_updates_rec > 0 )
  {
    if(bwest_str->in_wait_period > 0 )
    {
      bwest_str->in_wait_period--;
    }

    bwest_str->inWaitLatePkts -= ((bwest_str->inWaitLatePkts > 0)? 1:0);
    send_ts_diff = (float)(send_ts - bwest_str->prev_rec_send_ts);

    if (send_ts_diff <= (16 * frame_length)*2)
      //doesn't allow for a dropped packet, not sure necessary to be
      // that strict -DH
    {
      /* if not been updated for a long time, reduce the BN estimate */
      if((WebRtc_UWord32)(arr_ts - bwest_str->last_update_ts) *
         1000.0f / FS > 3000)
      {
        //how many frames should have been received since the last
        // update if too many have been dropped or there have been
        // big delays won't allow this reduction may no longer need
        // the send_ts_diff here
        num_pkts_expected = (int)(((float)(arr_ts -
                                           bwest_str->last_update_ts) * 1000.0f /(float) FS) /
                                  (float)frame_length);

        if(((float)bwest_str->num_pkts_rec/(float)num_pkts_expected) >
           0.9)
        {
          float inv_bitrate = (float) pow( 0.99995,
                                           (double)((WebRtc_UWord32)(arr_ts -
                                                                     bwest_str->last_reduction_ts)*1000.0f/FS) );

          if ( inv_bitrate )
          {
            bwest_str->rec_bw_inv /= inv_bitrate;

            //precautionary, likely never necessary
            if (bwest_str->hsn_detect_snd &&
                bwest_str->hsn_detect_rec)
            {
              if (bwest_str->rec_bw_inv > 0.000066f)
              {
                bwest_str->rec_bw_inv = 0.000066f;
              }
            }
          }
          else
          {
            bwest_str->rec_bw_inv = 1.0f /
                (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
          }
          /* reset time-since-update counter */
          bwest_str->last_reduction_ts = arr_ts;
        }
        else
          //reset here?
        {
          bwest_str->last_reduction_ts = arr_ts + 3*FS;
          bwest_str->last_update_ts = arr_ts;
          bwest_str->num_pkts_rec = 0;
        }
      }
    }
    else
    {
      bwest_str->last_reduction_ts = arr_ts + 3*FS;
      bwest_str->last_update_ts = arr_ts;
      bwest_str->num_pkts_rec = 0;
    }


    /* temporarily speed up adaptation if frame length has changed */
    if ( frame_length != bwest_str->prev_frame_length )
    {
      bwest_str->count_tot_updates_rec = 10;
      bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
          1000.0f / (float)frame_length;     /* bits/s */

      bwest_str->rec_bw_inv = 1.0f /((float)bwest_str->rec_bw +
                                     bwest_str->rec_header_rate);
    }

    ////////////////////////
    arr_ts_diff = (float)(arr_ts - bwest_str->prev_rec_arr_ts);

    if (send_ts_diff > 0 )
    {
      late_diff = arr_ts_diff - send_ts_diff;
    }
    else
    {
      late_diff = arr_ts_diff - (float)(16 * frame_length);
    }

    if((late_diff > 0) && !bwest_str->inWaitLatePkts)
    {
      bwest_str->numConsecLatePkts++;
      bwest_str->consecLatency += late_diff;
    }
    else
    {
      bwest_str->numConsecLatePkts = 0;
      bwest_str->consecLatency = 0;
    }
    if(bwest_str->numConsecLatePkts > 50)
    {
      float latencyMs = bwest_str->consecLatency/(FS/1000);
      float averageLatencyMs = latencyMs / bwest_str->numConsecLatePkts;
      delay_correction_factor = frame_length / (frame_length + averageLatencyMs);
      immediate_set = 1;
      bwest_str->inWaitLatePkts = (WebRtc_Word16)((bwest_str->consecLatency/(FS/1000)) / 30);// + 150;
      bwest_str->start_wait_period = arr_ts;
    }
    ///////////////////////////////////////////////



    /*   update only if previous packet was not lost */
    if ( rtp_number == bwest_str->prev_rec_rtp_number + 1 )
    {


      if (!(bwest_str->hsn_detect_snd && bwest_str->hsn_detect_rec))
      {
        if ((arr_ts_diff > (float)(16 * frame_length)))
        {
          //1/2 second
          if ((late_diff > 8000.0f) && !bwest_str->in_wait_period)
          {
            delay_correction_factor = 0.7f;
            bwest_str->in_wait_period = 55;
            bwest_str->start_wait_period = arr_ts;
            immediate_set = 1;
          }
          //320 ms
          else if (late_diff > 5120.0f && !bwest_str->in_wait_period)
          {
            delay_correction_factor = 0.8f;
            immediate_set = 1;
            bwest_str->in_wait_period = 44;
            bwest_str->start_wait_period = arr_ts;
          }
        }
      }


      if ((bwest_str->prev_rec_rtp_rate > bwest_str->rec_bw_avg) &&
          (rec_rtp_rate > bwest_str->rec_bw_avg)                 &&
          !bwest_str->in_wait_period)
      {
        /* test if still in initiation period and increment counter */
        if (bwest_str->count_tot_updates_rec++ > 99)
        {
          /* constant weight after initiation part */
          weight = 0.01f;
        }
        else
        {
          /* weight decreases with number of updates */
          weight = 1.0f / (float) bwest_str->count_tot_updates_rec;
        }
        /* Bottle Neck Estimation */

        /* limit outliers */
        /* if more than 25 ms too much */
        if (arr_ts_diff > frame_length * FS/1000 + 400.0f)
        {
          // in samples,  why 25ms??
          arr_ts_diff = frame_length * FS/1000 + 400.0f;
        }
        if(arr_ts_diff < (frame_length * FS/1000) - 160.0f)
        {
          /* don't allow it to be less than frame rate - 10 ms */
          arr_ts_diff = (float)frame_length * FS/1000 - 160.0f;
        }

        /* compute inverse receiving rate for last packet */
        curr_bw_inv = arr_ts_diff / ((float)(pksize + HEADER_SIZE) *
                                     8.0f * FS); // (180+35)*8*16000 = 27.5 Mbit....


        if(curr_bw_inv <
           (1.0f / (MAX_ISAC_BW + bwest_str->rec_header_rate)))
        {
          // don't allow inv rate to be larger than MAX
          curr_bw_inv = (1.0f /
                         (MAX_ISAC_BW + bwest_str->rec_header_rate));
        }

        /* update bottle neck rate estimate */
        bwest_str->rec_bw_inv = weight * curr_bw_inv +
            (1.0f - weight) * bwest_str->rec_bw_inv;

        /* reset time-since-update counter */
        bwest_str->last_update_ts    = arr_ts;
        bwest_str->last_reduction_ts = arr_ts + 3 * FS;
        bwest_str->num_pkts_rec = 0;

        /* Jitter Estimation */
        /* projected difference between arrival times */
        t_diff_proj = ((float)(pksize + HEADER_SIZE) * 8.0f *
                       1000.0f) / bwest_str->rec_bw_avg;


        // difference between projected and actual
        //   arrival time differences
        arr_time_noise = (float)(arr_ts_diff*1000.0f/FS) -
            t_diff_proj;
        arr_time_noise_abs = (float) fabs( arr_time_noise );

        /* long term averaged absolute jitter */
        bwest_str->rec_jitter = weight * arr_time_noise_abs +
            (1.0f - weight) * bwest_str->rec_jitter;
        if (bwest_str->rec_jitter > 10.0f)
        {
          bwest_str->rec_jitter = 10.0f;
        }
        /* short term averaged absolute jitter */
        bwest_str->rec_jitter_short_term_abs = 0.05f *
            arr_time_noise_abs + 0.95f *
            bwest_str->rec_jitter_short_term_abs;

        /* short term averaged jitter */
        bwest_str->rec_jitter_short_term = 0.05f * arr_time_noise +
            0.95f * bwest_str->rec_jitter_short_term;
      }
    }
  }
  else
  {
    // reset time-since-update counter when
    // receiving the first 9 packets
    bwest_str->last_update_ts    = arr_ts;
    bwest_str->last_reduction_ts = arr_ts + 3*FS;
    bwest_str->num_pkts_rec = 0;

    bwest_str->count_tot_updates_rec++;
  }

  /* limit minimum bottle neck rate */
  if (bwest_str->rec_bw_inv > 1.0f / ((float)MIN_ISAC_BW +
                                      bwest_str->rec_header_rate))
  {
    bwest_str->rec_bw_inv = 1.0f / ((float)MIN_ISAC_BW +
                                    bwest_str->rec_header_rate);
  }

  // limit maximum bitrate
  if (bwest_str->rec_bw_inv < 1.0f / ((float)MAX_ISAC_BW +
                                      bwest_str->rec_header_rate))
  {
    bwest_str->rec_bw_inv = 1.0f / ((float)MAX_ISAC_BW +
                                    bwest_str->rec_header_rate);
  }

  /* store frame length */
  bwest_str->prev_frame_length = frame_length;

  /* store far-side transmission rate */
  bwest_str->prev_rec_rtp_rate = rec_rtp_rate;

  /* store far-side RTP time stamp */
  bwest_str->prev_rec_rtp_number = rtp_number;

  // Replace bwest_str->rec_max_delay by the new
  // value (atomic operation)
  bwest_str->rec_max_delay = 3.0f * bwest_str->rec_jitter;

  /* store send and arrival time stamp */
  bwest_str->prev_rec_arr_ts = arr_ts ;
  bwest_str->prev_rec_send_ts = send_ts;

  /* Replace bwest_str->rec_bw by the new value (atomic operation) */
  bwest_str->rec_bw = (WebRtc_Word32)(1.0f / bwest_str->rec_bw_inv -
                                      bwest_str->rec_header_rate);

  if (immediate_set)
  {
    bwest_str->rec_bw = (WebRtc_Word32) (delay_correction_factor *
                                         (float) bwest_str->rec_bw);

    if (bwest_str->rec_bw < (WebRtc_Word32) MIN_ISAC_BW)
    {
      bwest_str->rec_bw = (WebRtc_Word32) MIN_ISAC_BW;
    }

    bwest_str->rec_bw_avg = bwest_str->rec_bw +
        bwest_str->rec_header_rate;

    bwest_str->rec_bw_avg_Q = (float) bwest_str->rec_bw;

    bwest_str->rec_jitter_short_term = 0.0f;

    bwest_str->rec_bw_inv = 1.0f / (bwest_str->rec_bw +
                                    bwest_str->rec_header_rate);

    bwest_str->count_tot_updates_rec = 1;

    immediate_set = 0;
    bwest_str->consecLatency = 0;
    bwest_str->numConsecLatePkts = 0;
  }

  return 0;
}


/* This function updates the send bottle neck rate                                                   */
/* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
/* returns 0 if everything went fine, -1 otherwise                                                   */
WebRtc_Word16 WebRtcIsac_UpdateUplinkBwImpl(
    BwEstimatorstr*           bwest_str,
    WebRtc_Word16               index,
    enum IsacSamplingRate encoderSamplingFreq)
{
  if((index < 0) || (index > 23))
  {
    return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
  }

  /* UPDATE ESTIMATES FROM OTHER SIDE */
  if(encoderSamplingFreq == kIsacWideband)
  {
    if(index > 11)
    {
      index -= 12;   
      /* compute the jitter estimate as decoded on the other side */
      bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
          0.1f * (float)MAX_ISAC_MD;
    }
    else
    {
      /* compute the jitter estimate as decoded on the other side */
      bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
          0.1f * (float)MIN_ISAC_MD;
    }

    /* compute the BN estimate as decoded on the other side */
    bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
        0.1f * kQRateTableWb[index];
  }
  else
  {
    /* compute the BN estimate as decoded on the other side */
    bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
        0.1f * kQRateTableSwb[index];
  }

  if (bwest_str->send_bw_avg > (float) 28000 && !bwest_str->hsn_detect_snd)
  {
    bwest_str->num_consec_snt_pkts_over_30k++;

    if (bwest_str->num_consec_snt_pkts_over_30k >= 66)
    {
      //approx 2 seconds with 30ms frames
      bwest_str->hsn_detect_snd = 1;
    }
  }
  else if (!bwest_str->hsn_detect_snd)
  {
    bwest_str->num_consec_snt_pkts_over_30k = 0;
  }
  return 0;
}

// called when there is upper-band bit-stream to update jitter
// statistics.
WebRtc_Word16 WebRtcIsac_UpdateUplinkJitter(
    BwEstimatorstr*              bwest_str,
    WebRtc_Word32                  index)
{
  if((index < 0) || (index > 23))
  {
    return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
  }

  if(index > 0)
  {
    /* compute the jitter estimate as decoded on the other side */
    bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
        0.1f * (float)MAX_ISAC_MD;
  }
  else
  {
    /* compute the jitter estimate as decoded on the other side */
    bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
        0.1f * (float)MIN_ISAC_MD;
  }

  return 0;
}



// Returns the bandwidth/jitter estimation code (integer 0...23)
// to put in the sending iSAC payload
WebRtc_UWord16
WebRtcIsac_GetDownlinkBwJitIndexImpl(
    BwEstimatorstr*           bwest_str,
    WebRtc_Word16*              bottleneckIndex,
    WebRtc_Word16*              jitterInfo,
    enum IsacSamplingRate decoderSamplingFreq)
{
  float MaxDelay;
  //WebRtc_UWord16 MaxDelayBit;

  float rate;
  float r;
  float e1, e2;
  const float weight = 0.1f;
  const float* ptrQuantizationTable;
  WebRtc_Word16 addJitterInfo;
  WebRtc_Word16 minInd;
  WebRtc_Word16 maxInd;
  WebRtc_Word16 midInd;

  /* Get Max Delay Bit */
  /* get unquantized max delay */
  MaxDelay = (float)WebRtcIsac_GetDownlinkMaxDelay(bwest_str);

  if ( ((1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
        MAX_ISAC_MD - MaxDelay) > (MaxDelay - (1.f-weight) *
                                   bwest_str->rec_max_delay_avg_Q - weight * MIN_ISAC_MD) )
  {
    jitterInfo[0] = 0;
    /* update quantized average */
    bwest_str->rec_max_delay_avg_Q =
        (1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
        (float)MIN_ISAC_MD;
  }
  else
  {
    jitterInfo[0] = 1;
    /* update quantized average */
    bwest_str->rec_max_delay_avg_Q =
        (1.f-weight) * bwest_str->rec_max_delay_avg_Q + weight *
        (float)MAX_ISAC_MD;
  }

  // Get unquantized rate.
  rate = (float)WebRtcIsac_GetDownlinkBandwidth(bwest_str);

  /* Get Rate Index */
  if(decoderSamplingFreq == kIsacWideband)
  {
    ptrQuantizationTable = kQRateTableWb;
    addJitterInfo = 1;
    maxInd = 11;
  }
  else
  {
    ptrQuantizationTable = kQRateTableSwb;
    addJitterInfo = 0;
    maxInd = 23;
  }

  minInd = 0;
  while(maxInd > minInd + 1)
  {
    midInd = (maxInd + minInd) >> 1;
    if(rate > ptrQuantizationTable[midInd])
    {
      minInd = midInd;
    }
    else
    {
      maxInd = midInd;
    }
  }
  // Chose the index which gives results an average which is closest
  // to rate
  r = (1 - weight) * bwest_str->rec_bw_avg_Q - rate;
  e1 = weight * ptrQuantizationTable[minInd] + r;
  e2 = weight * ptrQuantizationTable[maxInd] + r;
  e1 = (e1 > 0)? e1:-e1;
  e2 = (e2 > 0)? e2:-e2;
  if(e1 < e2)
  {
    bottleneckIndex[0] = minInd;
  }
  else
  {
    bottleneckIndex[0] = maxInd;
  }

  bwest_str->rec_bw_avg_Q = (1 - weight) * bwest_str->rec_bw_avg_Q +
      weight * ptrQuantizationTable[bottleneckIndex[0]];
  bottleneckIndex[0] += jitterInfo[0] * 12 * addJitterInfo;

  bwest_str->rec_bw_avg = (1 - weight) * bwest_str->rec_bw_avg + weight *
      (rate + bwest_str->rec_header_rate);

  return 0;
}



/* get the bottle neck rate from far side to here, as estimated on this side */
WebRtc_Word32 WebRtcIsac_GetDownlinkBandwidth( const BwEstimatorstr *bwest_str)
{
  WebRtc_Word32  rec_bw;
  float   jitter_sign;
  float   bw_adjust;

  /* create a value between -1.0 and 1.0 indicating "average sign" of jitter */
  jitter_sign = bwest_str->rec_jitter_short_term /
      bwest_str->rec_jitter_short_term_abs;

  /* adjust bw proportionally to negative average jitter sign */
  bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);

  /* adjust Rate if jitter sign is mostly constant */
  rec_bw = (WebRtc_Word32)(bwest_str->rec_bw * bw_adjust);

  /* limit range of bottle neck rate */
  if (rec_bw < MIN_ISAC_BW)
  {
    rec_bw = MIN_ISAC_BW;
  }
  else if (rec_bw > MAX_ISAC_BW)
  {
    rec_bw = MAX_ISAC_BW;
  }
  return rec_bw;
}

/* Returns the max delay (in ms) */
WebRtc_Word32
WebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str)
{
  WebRtc_Word32 rec_max_delay;

  rec_max_delay = (WebRtc_Word32)(bwest_str->rec_max_delay);

  /* limit range of jitter estimate */
  if (rec_max_delay < MIN_ISAC_MD)
  {
    rec_max_delay = MIN_ISAC_MD;
  }
  else if (rec_max_delay > MAX_ISAC_MD)
  {
    rec_max_delay = MAX_ISAC_MD;
  }
  return rec_max_delay;
}

/* get the bottle neck rate from here to far side, as estimated by far side */
void
WebRtcIsac_GetUplinkBandwidth(
    const BwEstimatorstr* bwest_str,
    WebRtc_Word32*          bitRate)
{
  /* limit range of bottle neck rate */
  if (bwest_str->send_bw_avg < MIN_ISAC_BW)
  {
    *bitRate = MIN_ISAC_BW;
  }
  else if (bwest_str->send_bw_avg > MAX_ISAC_BW)
  {
    *bitRate = MAX_ISAC_BW;
  }
  else
  {
    *bitRate = (WebRtc_Word32)(bwest_str->send_bw_avg);
  }
  return;
}

/* Returns the max delay value from the other side in ms */
WebRtc_Word32
WebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr *bwest_str)
{
  WebRtc_Word32 send_max_delay;

  send_max_delay = (WebRtc_Word32)(bwest_str->send_max_delay_avg);

  /* limit range of jitter estimate */
  if (send_max_delay < MIN_ISAC_MD)
  {
    send_max_delay = MIN_ISAC_MD;
  }
  else if (send_max_delay > MAX_ISAC_MD)
  {
    send_max_delay = MAX_ISAC_MD;
  }
  return send_max_delay;
}


/*
 * update long-term average bitrate and amount of data in buffer
 * returns minimum payload size (bytes)
 */
int WebRtcIsac_GetMinBytes(
    RateModel*         State,
    int                StreamSize,    /* bytes in bitstream */
    const int          FrameSamples,  /* samples per frame */
    const double       BottleNeck,    /* bottle neck rate; excl headers (bps) */
    const double       DelayBuildUp,  /* max delay from bottleneck buffering (ms) */
    enum ISACBandwidth bandwidth
    /*,WebRtc_Word16        frequentLargePackets*/)
{
  double MinRate = 0.0;
  int    MinBytes;
  double TransmissionTime;
  int    burstInterval = BURST_INTERVAL;

  // first 10 packets @ low rate, then INIT_BURST_LEN packets @
  // fixed rate of INIT_RATE bps
  if (State->InitCounter > 0)
  {
    if (State->InitCounter-- <= INIT_BURST_LEN)
    {
      if(bandwidth == isac8kHz)
      {
        MinRate = INIT_RATE_WB;
      }
      else
      {
        MinRate = INIT_RATE_SWB;
      }
    }
    else
    {
      MinRate = 0;
    }
  }
  else
  {
    /* handle burst */
    if (State->BurstCounter)
    {
      if (State->StillBuffered < (1.0 - 1.0/BURST_LEN) * DelayBuildUp)
      {
        /* max bps derived from BottleNeck and DelayBuildUp values */
        MinRate = (1.0 + (FS/1000) * DelayBuildUp /
                   (double)(BURST_LEN * FrameSamples)) * BottleNeck;
      }
      else
      {
        // max bps derived from StillBuffered and DelayBuildUp
        // values
        MinRate = (1.0 + (FS/1000) * (DelayBuildUp -
                                      State->StillBuffered) / (double)FrameSamples) * BottleNeck;
        if (MinRate < 1.04 * BottleNeck)
        {
          MinRate = 1.04 * BottleNeck;
        }
      }
      State->BurstCounter--;
    }
  }


  /* convert rate from bits/second to bytes/packet */
  MinBytes = (int) (MinRate * FrameSamples / (8.0 * FS));

  /* StreamSize will be adjusted if less than MinBytes */
  if (StreamSize < MinBytes)
  {
    StreamSize = MinBytes;
  }

  /* keep track of when bottle neck was last exceeded by at least 1% */
  if (StreamSize * 8.0 * FS / FrameSamples > 1.01 * BottleNeck) {
    if (State->PrevExceed) {
      /* bottle_neck exceded twice in a row, decrease ExceedAgo */
      State->ExceedAgo -= /*BURST_INTERVAL*/ burstInterval / (BURST_LEN - 1);
      if (State->ExceedAgo < 0)
        State->ExceedAgo = 0;
    }
    else
    {
      State->ExceedAgo += (FrameSamples * 1000) / FS; /* ms */
      State->PrevExceed = 1;
    }
  }
  else
  {
    State->PrevExceed = 0;
    State->ExceedAgo += (FrameSamples * 1000) / FS;     /* ms */
  }

  /* set burst flag if bottle neck not exceeded for long time */
  if ((State->ExceedAgo > burstInterval) &&
      (State->BurstCounter == 0))
  {
    if (State->PrevExceed)
    {
      State->BurstCounter = BURST_LEN - 1;
    }
    else
    {
      State->BurstCounter = BURST_LEN;
    }
  }


  /* Update buffer delay */
  TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck;  /* ms */
  State->StillBuffered += TransmissionTime;
  State->StillBuffered -= (FrameSamples * 1000) / FS;     /* ms */
  if (State->StillBuffered < 0.0)
  {
    State->StillBuffered = 0.0;
  }

  return MinBytes;
}


/*
 * update long-term average bitrate and amount of data in buffer
 */
void WebRtcIsac_UpdateRateModel(
    RateModel *State,
    int StreamSize,                    /* bytes in bitstream */
    const int FrameSamples,            /* samples per frame */
    const double BottleNeck)        /* bottle neck rate; excl headers (bps) */
{
  double TransmissionTime;

  /* avoid the initial "high-rate" burst */
  State->InitCounter = 0;

  /* Update buffer delay */
  TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck;  /* ms */
  State->StillBuffered += TransmissionTime;
  State->StillBuffered -= (FrameSamples * 1000) / FS;     /* ms */
  if (State->StillBuffered < 0.0)
    State->StillBuffered = 0.0;

}


void WebRtcIsac_InitRateModel(
    RateModel *State)
{
  State->PrevExceed      = 0;                        /* boolean */
  State->ExceedAgo       = 0;                        /* ms */
  State->BurstCounter    = 0;                        /* packets */
  State->InitCounter     = INIT_BURST_LEN + 10;    /* packets */
  State->StillBuffered   = 1.0;                    /* ms */
}

int WebRtcIsac_GetNewFrameLength(
    double bottle_neck,
    int    current_framesamples)
{
  int new_framesamples;

  const int Thld_20_30 = 20000;

  //const int Thld_30_20 = 30000;
  const int Thld_30_20 = 1000000;   // disable 20 ms frames

  const int Thld_30_60 = 18000;
  //const int Thld_30_60 = 0;      // disable 60 ms frames

  const int Thld_60_30 = 27000;


  new_framesamples = current_framesamples;

  /* find new framelength */
  switch(current_framesamples) {
    case 320:
      if (bottle_neck < Thld_20_30)
        new_framesamples = 480;
      break;
    case 480:
      if (bottle_neck < Thld_30_60)
        new_framesamples = 960;
      else if (bottle_neck > Thld_30_20)
        new_framesamples = 320;
      break;
    case 960:
      if (bottle_neck >= Thld_60_30)
        new_framesamples = 480;
      break;
  }

  return new_framesamples;
}

double WebRtcIsac_GetSnr(
    double bottle_neck,
    int    framesamples)
{
  double s2nr;

  const double a_20 = -30.0;
  const double b_20 = 0.8;
  const double c_20 = 0.0;

  const double a_30 = -23.0;
  const double b_30 = 0.48;
  const double c_30 = 0.0;

  const double a_60 = -23.0;
  const double b_60 = 0.53;
  const double c_60 = 0.0;


  /* find new SNR value */
  switch(framesamples) {
    case 320:
      s2nr = a_20 + b_20 * bottle_neck * 0.001 + c_20 * bottle_neck *
          bottle_neck * 0.000001;
      break;
    case 480:
      s2nr = a_30 + b_30 * bottle_neck * 0.001 + c_30 * bottle_neck *
          bottle_neck * 0.000001;
      break;
    case 960:
      s2nr = a_60 + b_60 * bottle_neck * 0.001 + c_60 * bottle_neck *
          bottle_neck * 0.000001;
      break;
    default:
      s2nr = 0;
  }

  return s2nr;

}
