/*
 *  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 "webrtc/rtc_base/checks.h"

#include <math.h>
#include <string.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,
};




int32_t 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            = (int32_t)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            = (int32_t)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;

  bwest_str->external_bw_info.in_use = 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                                                   */
int16_t WebRtcIsac_UpdateBandwidthEstimator(
    BwEstimatorstr* bwest_str,
    const uint16_t rtp_number,
    const int32_t frame_length,
    const uint32_t send_ts,
    const uint32_t arr_ts,
    const size_t pksize
    /*,    const uint16_t 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;

  RTC_DCHECK(!bwest_str->external_bw_info.in_use);

  // 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((uint32_t)(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)((uint32_t)(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 = (int16_t)((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 = (int32_t)(1.0f / bwest_str->rec_bw_inv -
                                      bwest_str->rec_header_rate);

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

    if (bwest_str->rec_bw < (int32_t) MIN_ISAC_BW)
    {
      bwest_str->rec_bw = (int32_t) 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                                                   */
int16_t WebRtcIsac_UpdateUplinkBwImpl(
    BwEstimatorstr*           bwest_str,
    int16_t               index,
    enum IsacSamplingRate encoderSamplingFreq)
{
  RTC_DCHECK(!bwest_str->external_bw_info.in_use);

  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.
int16_t WebRtcIsac_UpdateUplinkJitter(
    BwEstimatorstr*              bwest_str,
    int32_t                  index)
{
  RTC_DCHECK(!bwest_str->external_bw_info.in_use);

  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
void
WebRtcIsac_GetDownlinkBwJitIndexImpl(
    BwEstimatorstr*           bwest_str,
    int16_t*              bottleneckIndex,
    int16_t*              jitterInfo,
    enum IsacSamplingRate decoderSamplingFreq)
{
  float MaxDelay;
  //uint16_t MaxDelayBit;

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

  if (bwest_str->external_bw_info.in_use) {
    *bottleneckIndex = bwest_str->external_bw_info.bottleneck_idx;
    *jitterInfo = bwest_str->external_bw_info.jitter_info;
    return;
  }

  /* 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);
}



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

  RTC_DCHECK(!bwest_str->external_bw_info.in_use);

  /* 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 = (int32_t)(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) */
int32_t
WebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str)
{
  int32_t rec_max_delay;

  RTC_DCHECK(!bwest_str->external_bw_info.in_use);

  rec_max_delay = (int32_t)(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;
}

/* Clamp val to the closed interval [min,max]. */
static int32_t clamp(int32_t val, int32_t min, int32_t max) {
  RTC_DCHECK_LE(min, max);
  return val < min ? min : (val > max ? max : val);
}

int32_t WebRtcIsac_GetUplinkBandwidth(const BwEstimatorstr* bwest_str) {
  return bwest_str->external_bw_info.in_use
             ? bwest_str->external_bw_info.send_bw_avg
             : clamp(bwest_str->send_bw_avg, MIN_ISAC_BW, MAX_ISAC_BW);
}

int32_t WebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr* bwest_str) {
  return bwest_str->external_bw_info.in_use
             ? bwest_str->external_bw_info.send_max_delay_avg
             : clamp(bwest_str->send_max_delay_avg, MIN_ISAC_MD, MAX_ISAC_MD);
}

void WebRtcIsacBw_GetBandwidthInfo(BwEstimatorstr* bwest_str,
                                   enum IsacSamplingRate decoder_sample_rate_hz,
                                   IsacBandwidthInfo* bwinfo) {
  RTC_DCHECK(!bwest_str->external_bw_info.in_use);
  bwinfo->in_use = 1;
  bwinfo->send_bw_avg = WebRtcIsac_GetUplinkBandwidth(bwest_str);
  bwinfo->send_max_delay_avg = WebRtcIsac_GetUplinkMaxDelay(bwest_str);
  WebRtcIsac_GetDownlinkBwJitIndexImpl(bwest_str, &bwinfo->bottleneck_idx,
                                       &bwinfo->jitter_info,
                                       decoder_sample_rate_hz);
}

void WebRtcIsacBw_SetBandwidthInfo(BwEstimatorstr* bwest_str,
                                   const IsacBandwidthInfo* bwinfo) {
  memcpy(&bwest_str->external_bw_info, bwinfo,
         sizeof bwest_str->external_bw_info);
}

/*
 * 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
    /*,int16_t        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;

}
