16f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/*
26f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
36f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *
46f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  Use of this source code is governed by a BSD-style license
56f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  that can be found in the LICENSE file in the root of the source
66f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  tree. An additional intellectual property rights grant can be found
76f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  in the file PATENTS.  All contributing project authors may
86f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *  be found in the AUTHORS file in the root of the source tree.
96f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */
106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/*
126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * BwEstimator.c
136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *
146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * This file contains the code for the Bandwidth Estimator designed
156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * for iSAC.
166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin *
176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */
186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "bandwidth_estimator.h"
206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "settings.h"
216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "isac.h"
226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include <math.h>
246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* array of quantization levels for bottle neck info; Matlab code: */
266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */
276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const float kQRateTableWb[12] =
286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  18859.8f, 20963.3f, 23301.4f, 25900.3f, 28789.0f, 32000.0f};
316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const float kQRateTableSwb[24] =
346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  18859.8f, 20963.3f, 23153.1f, 25342.9f, 27532.7f, 29722.5f,
376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  31912.3f, 34102.1f, 36291.9f, 38481.7f, 40671.4f, 42861.2f,
386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  45051.0f, 47240.8f, 49430.6f, 51620.4f, 53810.2f, 56000.0f,
396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin};
406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
446f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtc_Word32 WebRtcIsac_InitBandwidthEstimator(
456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    BwEstimatorstr*              bwest_str,
466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    enum IsacSamplingRate encoderSampRate,
476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    enum IsacSamplingRate decoderSampRate)
486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  switch(encoderSampRate)
506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case kIsacWideband:
526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->send_bw_avg       = INIT_BN_EST_WB;
546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        break;
556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case kIsacSuperWideband:
576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->send_bw_avg       = INIT_BN_EST_SWB;
596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        break;
606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  switch(decoderSampRate)
646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case kIsacWideband:
666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->prev_frame_length = INIT_FRAME_LEN_WB;
686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw_inv        = 1.0f /
696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw            = (WebRtc_Word32)INIT_BN_EST_WB;
716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw_avg_Q      = INIT_BN_EST_WB;
726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw_avg        = INIT_BN_EST_WB + INIT_HDR_RATE_WB;
736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_header_rate   = INIT_HDR_RATE_WB;
746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        break;
756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case kIsacSuperWideband:
776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->prev_frame_length = INIT_FRAME_LEN_SWB;
796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw_inv        = 1.0f /
806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            (INIT_BN_EST_SWB + INIT_HDR_RATE_SWB);
816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw            = (WebRtc_Word32)INIT_BN_EST_SWB;
826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw_avg_Q      = INIT_BN_EST_SWB;
836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw_avg        = INIT_BN_EST_SWB + INIT_HDR_RATE_SWB;
846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_header_rate   = INIT_HDR_RATE_SWB;
856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        break;
866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_rec_rtp_number       = 0;
906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_rec_arr_ts           = 0;
916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_rec_send_ts          = 0;
926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_rec_rtp_rate         = 1.0f;
936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->last_update_ts            = 0;
946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->last_reduction_ts         = 0;
956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->count_tot_updates_rec     = -9;
966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_jitter                = 10.0f;
976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_jitter_short_term     = 0.0f;
986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_jitter_short_term_abs = 5.0f;
996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_max_delay             = 10.0f;
1006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_max_delay_avg_Q       = 10.0f;
1016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->num_pkts_rec              = 0;
1026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->send_max_delay_avg        = 10.0f;
1046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->hsn_detect_rec = 0;
1066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->num_consec_rec_pkts_over_30k = 0;
1086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->hsn_detect_snd = 0;
1106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->num_consec_snt_pkts_over_30k = 0;
1126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->in_wait_period = 0;
1146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->change_to_WB = 0;
1166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->numConsecLatePkts = 0;
1186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->consecLatency = 0;
1196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->inWaitLatePkts = 0;
1206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->senderTimestamp = 0;
1216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->receiverTimestamp = 0;
1226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return 0;
1236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
1246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* This function updates both bottle neck rates                                                      */
1266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* Parameters:                                                                                       */
1276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* rtp_number    - value from RTP packet, from NetEq                                                 */
1286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* frame length  - length of signal frame in ms, from iSAC decoder                                   */
1296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* send_ts       - value in RTP header giving send time in samples                                     */
1306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* arr_ts        - value given by timeGetTime() time of arrival in samples of packet from NetEq      */
1316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* pksize        - size of packet in bytes, from NetEq                                               */
1326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
1336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* returns 0 if everything went fine, -1 otherwise                                                   */
1346f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtc_Word16 WebRtcIsac_UpdateBandwidthEstimator(
1356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    BwEstimatorstr *bwest_str,
1366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const WebRtc_UWord16 rtp_number,
1376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const WebRtc_Word32  frame_length,
1386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const WebRtc_UWord32 send_ts,
1396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const WebRtc_UWord32 arr_ts,
1406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const WebRtc_Word32  pksize
1416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /*,    const WebRtc_UWord16 Index*/)
1426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
1436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float weight = 0.0f;
1446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float curr_bw_inv = 0.0f;
1456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float rec_rtp_rate;
1466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float t_diff_proj;
1476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float arr_ts_diff;
1486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float send_ts_diff;
1496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float arr_time_noise;
1506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float arr_time_noise_abs;
1516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float delay_correction_factor = 1;
1536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float late_diff = 0.0f;
1546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int immediate_set = 0;
1556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int num_pkts_expected;
1566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // We have to adjust the header-rate if the first packet has a
1596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // frame-size different than the initialized value.
1606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if ( frame_length != bwest_str->prev_frame_length )
1616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
1626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
1636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        1000.0f / (float)frame_length;     /* bits/s */
1646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* UPDATE ESTIMATES ON THIS SIDE */
1676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* compute far-side transmission rate */
1686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  rec_rtp_rate = ((float)pksize * 8.0f * 1000.0f / (float)frame_length) +
1696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->rec_header_rate;
1706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // rec_rtp_rate packet bits/s + header bits/s
1716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* check for timer wrap-around */
1736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (arr_ts < bwest_str->prev_rec_arr_ts)
1746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
1756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->prev_rec_arr_ts   = arr_ts;
1766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->last_update_ts    = arr_ts;
1776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->last_reduction_ts = arr_ts + 3*FS;
1786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->num_pkts_rec      = 0;
1796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* store frame length */
1816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->prev_frame_length = frame_length;
1826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* store far-side transmission rate */
1846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->prev_rec_rtp_rate = rec_rtp_rate;
1856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* store far-side RTP time stamp */
1876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->prev_rec_rtp_number = rtp_number;
1886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
1906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->num_pkts_rec++;
1936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* check that it's not one of the first 9 packets */
1956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if ( bwest_str->count_tot_updates_rec > 0 )
1966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
1976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if(bwest_str->in_wait_period > 0 )
1986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
1996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->in_wait_period--;
2006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
2016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->inWaitLatePkts -= ((bwest_str->inWaitLatePkts > 0)? 1:0);
2036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    send_ts_diff = (float)(send_ts - bwest_str->prev_rec_send_ts);
2046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (send_ts_diff <= (16 * frame_length)*2)
2066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      //doesn't allow for a dropped packet, not sure necessary to be
2076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      // that strict -DH
2086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
2096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      /* if not been updated for a long time, reduce the BN estimate */
2106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if((WebRtc_UWord32)(arr_ts - bwest_str->last_update_ts) *
2116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin         1000.0f / FS > 3000)
2126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
2136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        //how many frames should have been received since the last
2146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // update if too many have been dropped or there have been
2156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // big delays won't allow this reduction may no longer need
2166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // the send_ts_diff here
2176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        num_pkts_expected = (int)(((float)(arr_ts -
2186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                           bwest_str->last_update_ts) * 1000.0f /(float) FS) /
2196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                  (float)frame_length);
2206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if(((float)bwest_str->num_pkts_rec/(float)num_pkts_expected) >
2226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin           0.9)
2236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
2246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          float inv_bitrate = (float) pow( 0.99995,
2256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                           (double)((WebRtc_UWord32)(arr_ts -
2266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                                                     bwest_str->last_reduction_ts)*1000.0f/FS) );
2276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          if ( inv_bitrate )
2296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          {
2306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            bwest_str->rec_bw_inv /= inv_bitrate;
2316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            //precautionary, likely never necessary
2336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            if (bwest_str->hsn_detect_snd &&
2346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                bwest_str->hsn_detect_rec)
2356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            {
2366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin              if (bwest_str->rec_bw_inv > 0.000066f)
2376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin              {
2386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                bwest_str->rec_bw_inv = 0.000066f;
2396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin              }
2406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            }
2416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          }
2426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          else
2436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          {
2446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            bwest_str->rec_bw_inv = 1.0f /
2456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
2466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          }
2476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          /* reset time-since-update counter */
2486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          bwest_str->last_reduction_ts = arr_ts;
2496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
2506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        else
2516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          //reset here?
2526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
2536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          bwest_str->last_reduction_ts = arr_ts + 3*FS;
2546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          bwest_str->last_update_ts = arr_ts;
2556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          bwest_str->num_pkts_rec = 0;
2566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
2576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
2586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
2596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else
2606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
2616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->last_reduction_ts = arr_ts + 3*FS;
2626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->last_update_ts = arr_ts;
2636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->num_pkts_rec = 0;
2646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
2656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* temporarily speed up adaptation if frame length has changed */
2686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if ( frame_length != bwest_str->prev_frame_length )
2696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
2706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->count_tot_updates_rec = 10;
2716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
2726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          1000.0f / (float)frame_length;     /* bits/s */
2736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->rec_bw_inv = 1.0f /((float)bwest_str->rec_bw +
2756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                     bwest_str->rec_header_rate);
2766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
2776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    ////////////////////////
2796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    arr_ts_diff = (float)(arr_ts - bwest_str->prev_rec_arr_ts);
2806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (send_ts_diff > 0 )
2826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
2836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      late_diff = arr_ts_diff - send_ts_diff;
2846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
2856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else
2866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
2876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      late_diff = arr_ts_diff - (float)(16 * frame_length);
2886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
2896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if((late_diff > 0) && !bwest_str->inWaitLatePkts)
2916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
2926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->numConsecLatePkts++;
2936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->consecLatency += late_diff;
2946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
2956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else
2966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
2976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->numConsecLatePkts = 0;
2986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->consecLatency = 0;
2996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
3006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if(bwest_str->numConsecLatePkts > 50)
3016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
3026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      float latencyMs = bwest_str->consecLatency/(FS/1000);
3036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      float averageLatencyMs = latencyMs / bwest_str->numConsecLatePkts;
3046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      delay_correction_factor = frame_length / (frame_length + averageLatencyMs);
3056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      immediate_set = 1;
3066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->inWaitLatePkts = (WebRtc_Word16)((bwest_str->consecLatency/(FS/1000)) / 30);// + 150;
3076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->start_wait_period = arr_ts;
3086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
3096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    ///////////////////////////////////////////////
3106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /*   update only if previous packet was not lost */
3146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if ( rtp_number == bwest_str->prev_rec_rtp_number + 1 )
3156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
3166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if (!(bwest_str->hsn_detect_snd && bwest_str->hsn_detect_rec))
3196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
3206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if ((arr_ts_diff > (float)(16 * frame_length)))
3216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
3226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          //1/2 second
3236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          if ((late_diff > 8000.0f) && !bwest_str->in_wait_period)
3246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          {
3256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            delay_correction_factor = 0.7f;
3266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            bwest_str->in_wait_period = 55;
3276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            bwest_str->start_wait_period = arr_ts;
3286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            immediate_set = 1;
3296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          }
3306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          //320 ms
3316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          else if (late_diff > 5120.0f && !bwest_str->in_wait_period)
3326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          {
3336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            delay_correction_factor = 0.8f;
3346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            immediate_set = 1;
3356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            bwest_str->in_wait_period = 44;
3366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            bwest_str->start_wait_period = arr_ts;
3376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          }
3386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
3396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
3406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if ((bwest_str->prev_rec_rtp_rate > bwest_str->rec_bw_avg) &&
3436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          (rec_rtp_rate > bwest_str->rec_bw_avg)                 &&
3446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          !bwest_str->in_wait_period)
3456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
3466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* test if still in initiation period and increment counter */
3476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if (bwest_str->count_tot_updates_rec++ > 99)
3486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
3496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          /* constant weight after initiation part */
3506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          weight = 0.01f;
3516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
3526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        else
3536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
3546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          /* weight decreases with number of updates */
3556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          weight = 1.0f / (float) bwest_str->count_tot_updates_rec;
3566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
3576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* Bottle Neck Estimation */
3586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* limit outliers */
3606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* if more than 25 ms too much */
3616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if (arr_ts_diff > frame_length * FS/1000 + 400.0f)
3626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
3636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          // in samples,  why 25ms??
3646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          arr_ts_diff = frame_length * FS/1000 + 400.0f;
3656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
3666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if(arr_ts_diff < (frame_length * FS/1000) - 160.0f)
3676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
3686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          /* don't allow it to be less than frame rate - 10 ms */
3696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          arr_ts_diff = (float)frame_length * FS/1000 - 160.0f;
3706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
3716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* compute inverse receiving rate for last packet */
3736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        curr_bw_inv = arr_ts_diff / ((float)(pksize + HEADER_SIZE) *
3746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                     8.0f * FS); // (180+35)*8*16000 = 27.5 Mbit....
3756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if(curr_bw_inv <
3786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin           (1.0f / (MAX_ISAC_BW + bwest_str->rec_header_rate)))
3796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
3806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          // don't allow inv rate to be larger than MAX
3816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          curr_bw_inv = (1.0f /
3826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                         (MAX_ISAC_BW + bwest_str->rec_header_rate));
3836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
3846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* update bottle neck rate estimate */
3866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_bw_inv = weight * curr_bw_inv +
3876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            (1.0f - weight) * bwest_str->rec_bw_inv;
3886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* reset time-since-update counter */
3906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->last_update_ts    = arr_ts;
3916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->last_reduction_ts = arr_ts + 3 * FS;
3926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->num_pkts_rec = 0;
3936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* Jitter Estimation */
3956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* projected difference between arrival times */
3966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        t_diff_proj = ((float)(pksize + HEADER_SIZE) * 8.0f *
3976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                       1000.0f) / bwest_str->rec_bw_avg;
3986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // difference between projected and actual
4016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        //   arrival time differences
4026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        arr_time_noise = (float)(arr_ts_diff*1000.0f/FS) -
4036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            t_diff_proj;
4046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        arr_time_noise_abs = (float) fabs( arr_time_noise );
4056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* long term averaged absolute jitter */
4076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_jitter = weight * arr_time_noise_abs +
4086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            (1.0f - weight) * bwest_str->rec_jitter;
4096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if (bwest_str->rec_jitter > 10.0f)
4106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
4116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          bwest_str->rec_jitter = 10.0f;
4126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
4136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* short term averaged absolute jitter */
4146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_jitter_short_term_abs = 0.05f *
4156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            arr_time_noise_abs + 0.95f *
4166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            bwest_str->rec_jitter_short_term_abs;
4176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* short term averaged jitter */
4196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_jitter_short_term = 0.05f * arr_time_noise +
4206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            0.95f * bwest_str->rec_jitter_short_term;
4216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
4226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
4236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
4246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
4256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
4266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    // reset time-since-update counter when
4276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    // receiving the first 9 packets
4286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->last_update_ts    = arr_ts;
4296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->last_reduction_ts = arr_ts + 3*FS;
4306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->num_pkts_rec = 0;
4316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->count_tot_updates_rec++;
4336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
4346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* limit minimum bottle neck rate */
4366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (bwest_str->rec_bw_inv > 1.0f / ((float)MIN_ISAC_BW +
4376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                      bwest_str->rec_header_rate))
4386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
4396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_bw_inv = 1.0f / ((float)MIN_ISAC_BW +
4406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                    bwest_str->rec_header_rate);
4416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
4426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // limit maximum bitrate
4446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (bwest_str->rec_bw_inv < 1.0f / ((float)MAX_ISAC_BW +
4456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                      bwest_str->rec_header_rate))
4466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
4476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_bw_inv = 1.0f / ((float)MAX_ISAC_BW +
4486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                    bwest_str->rec_header_rate);
4496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
4506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* store frame length */
4526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_frame_length = frame_length;
4536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* store far-side transmission rate */
4556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_rec_rtp_rate = rec_rtp_rate;
4566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* store far-side RTP time stamp */
4586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_rec_rtp_number = rtp_number;
4596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // Replace bwest_str->rec_max_delay by the new
4616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // value (atomic operation)
4626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_max_delay = 3.0f * bwest_str->rec_jitter;
4636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* store send and arrival time stamp */
4656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_rec_arr_ts = arr_ts ;
4666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->prev_rec_send_ts = send_ts;
4676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* Replace bwest_str->rec_bw by the new value (atomic operation) */
4696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_bw = (WebRtc_Word32)(1.0f / bwest_str->rec_bw_inv -
4706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                      bwest_str->rec_header_rate);
4716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (immediate_set)
4736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
4746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_bw = (WebRtc_Word32) (delay_correction_factor *
4756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                         (float) bwest_str->rec_bw);
4766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (bwest_str->rec_bw < (WebRtc_Word32) MIN_ISAC_BW)
4786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
4796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->rec_bw = (WebRtc_Word32) MIN_ISAC_BW;
4806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
4816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_bw_avg = bwest_str->rec_bw +
4836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        bwest_str->rec_header_rate;
4846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_bw_avg_Q = (float) bwest_str->rec_bw;
4866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_jitter_short_term = 0.0f;
4886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_bw_inv = 1.0f / (bwest_str->rec_bw +
4906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                    bwest_str->rec_header_rate);
4916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->count_tot_updates_rec = 1;
4936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    immediate_set = 0;
4956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->consecLatency = 0;
4966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->numConsecLatePkts = 0;
4976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
4986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return 0;
5006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
5016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* This function updates the send bottle neck rate                                                   */
5046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
5056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* returns 0 if everything went fine, -1 otherwise                                                   */
5066f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtc_Word16 WebRtcIsac_UpdateUplinkBwImpl(
5076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    BwEstimatorstr*           bwest_str,
5086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtc_Word16               index,
5096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    enum IsacSamplingRate encoderSamplingFreq)
5106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
5116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if((index < 0) || (index > 23))
5126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
5136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
5146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
5156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* UPDATE ESTIMATES FROM OTHER SIDE */
5176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if(encoderSamplingFreq == kIsacWideband)
5186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
5196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if(index > 11)
5206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
5216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      index -= 12;
5226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      /* compute the jitter estimate as decoded on the other side */
5236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
5246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          0.1f * (float)MAX_ISAC_MD;
5256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
5266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else
5276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
5286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      /* compute the jitter estimate as decoded on the other side */
5296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
5306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          0.1f * (float)MIN_ISAC_MD;
5316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
5326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* compute the BN estimate as decoded on the other side */
5346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
5356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        0.1f * kQRateTableWb[index];
5366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
5376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
5386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
5396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* compute the BN estimate as decoded on the other side */
5406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
5416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        0.1f * kQRateTableSwb[index];
5426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
5436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (bwest_str->send_bw_avg > (float) 28000 && !bwest_str->hsn_detect_snd)
5456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
5466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->num_consec_snt_pkts_over_30k++;
5476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (bwest_str->num_consec_snt_pkts_over_30k >= 66)
5496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
5506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      //approx 2 seconds with 30ms frames
5516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->hsn_detect_snd = 1;
5526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
5536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
5546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else if (!bwest_str->hsn_detect_snd)
5556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
5566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->num_consec_snt_pkts_over_30k = 0;
5576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
5586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return 0;
5596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
5606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// called when there is upper-band bit-stream to update jitter
5626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// statistics.
5636f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtc_Word16 WebRtcIsac_UpdateUplinkJitter(
5646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    BwEstimatorstr*              bwest_str,
5656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtc_Word32                  index)
5666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
5676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if((index < 0) || (index > 23))
5686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
5696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
5706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
5716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if(index > 0)
5736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
5746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* compute the jitter estimate as decoded on the other side */
5756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
5766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        0.1f * (float)MAX_ISAC_MD;
5776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
5786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
5796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
5806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* compute the jitter estimate as decoded on the other side */
5816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
5826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        0.1f * (float)MIN_ISAC_MD;
5836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
5846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return 0;
5866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
5876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
5906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// Returns the bandwidth/jitter estimation code (integer 0...23)
5916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// to put in the sending iSAC payload
5926f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtc_UWord16
5936f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtcIsac_GetDownlinkBwJitIndexImpl(
5946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    BwEstimatorstr*           bwest_str,
5956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtc_Word16*              bottleneckIndex,
5966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtc_Word16*              jitterInfo,
5976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    enum IsacSamplingRate decoderSamplingFreq)
5986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
5996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float MaxDelay;
6006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //WebRtc_UWord16 MaxDelayBit;
6016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float rate;
6036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float r;
6046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float e1, e2;
6056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const float weight = 0.1f;
6066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const float* ptrQuantizationTable;
6076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtc_Word16 addJitterInfo;
6086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtc_Word16 minInd;
6096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtc_Word16 maxInd;
6106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtc_Word16 midInd;
6116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* Get Max Delay Bit */
6136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* get unquantized max delay */
6146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  MaxDelay = (float)WebRtcIsac_GetDownlinkMaxDelay(bwest_str);
6156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if ( ((1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
6176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        MAX_ISAC_MD - MaxDelay) > (MaxDelay - (1.f-weight) *
6186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                   bwest_str->rec_max_delay_avg_Q - weight * MIN_ISAC_MD) )
6196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
6206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    jitterInfo[0] = 0;
6216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* update quantized average */
6226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_max_delay_avg_Q =
6236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        (1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
6246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        (float)MIN_ISAC_MD;
6256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
6266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
6276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
6286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    jitterInfo[0] = 1;
6296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* update quantized average */
6306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bwest_str->rec_max_delay_avg_Q =
6316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        (1.f-weight) * bwest_str->rec_max_delay_avg_Q + weight *
6326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        (float)MAX_ISAC_MD;
6336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
6346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // Get unquantized rate.
6366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  rate = (float)WebRtcIsac_GetDownlinkBandwidth(bwest_str);
6376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* Get Rate Index */
6396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if(decoderSamplingFreq == kIsacWideband)
6406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
6416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    ptrQuantizationTable = kQRateTableWb;
6426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    addJitterInfo = 1;
6436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    maxInd = 11;
6446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
6456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
6466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
6476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    ptrQuantizationTable = kQRateTableSwb;
6486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    addJitterInfo = 0;
6496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    maxInd = 23;
6506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
6516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  minInd = 0;
6536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  while(maxInd > minInd + 1)
6546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
6556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    midInd = (maxInd + minInd) >> 1;
6566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if(rate > ptrQuantizationTable[midInd])
6576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
6586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      minInd = midInd;
6596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
6606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else
6616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
6626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      maxInd = midInd;
6636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
6646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
6656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // Chose the index which gives results an average which is closest
6666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // to rate
6676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  r = (1 - weight) * bwest_str->rec_bw_avg_Q - rate;
6686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  e1 = weight * ptrQuantizationTable[minInd] + r;
6696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  e2 = weight * ptrQuantizationTable[maxInd] + r;
6706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  e1 = (e1 > 0)? e1:-e1;
6716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  e2 = (e2 > 0)? e2:-e2;
6726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if(e1 < e2)
6736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
6746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bottleneckIndex[0] = minInd;
6756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
6766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
6776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
6786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    bottleneckIndex[0] = maxInd;
6796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
6806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_bw_avg_Q = (1 - weight) * bwest_str->rec_bw_avg_Q +
6826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      weight * ptrQuantizationTable[bottleneckIndex[0]];
6836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bottleneckIndex[0] += jitterInfo[0] * 12 * addJitterInfo;
6846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bwest_str->rec_bw_avg = (1 - weight) * bwest_str->rec_bw_avg + weight *
6866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      (rate + bwest_str->rec_header_rate);
6876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return 0;
6896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
6906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
6936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* get the bottle neck rate from far side to here, as estimated on this side */
6946f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtc_Word32 WebRtcIsac_GetDownlinkBandwidth( const BwEstimatorstr *bwest_str)
6956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
6966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtc_Word32  rec_bw;
6976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float   jitter_sign;
6986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  float   bw_adjust;
6996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* create a value between -1.0 and 1.0 indicating "average sign" of jitter */
7016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  jitter_sign = bwest_str->rec_jitter_short_term /
7026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      bwest_str->rec_jitter_short_term_abs;
7036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* adjust bw proportionally to negative average jitter sign */
7056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
7066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* adjust Rate if jitter sign is mostly constant */
7086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  rec_bw = (WebRtc_Word32)(bwest_str->rec_bw * bw_adjust);
7096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* limit range of bottle neck rate */
7116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (rec_bw < MIN_ISAC_BW)
7126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    rec_bw = MIN_ISAC_BW;
7146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else if (rec_bw > MAX_ISAC_BW)
7166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    rec_bw = MAX_ISAC_BW;
7186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return rec_bw;
7206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
7216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* Returns the max delay (in ms) */
7236f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtc_Word32
7246f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str)
7256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
7266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtc_Word32 rec_max_delay;
7276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  rec_max_delay = (WebRtc_Word32)(bwest_str->rec_max_delay);
7296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* limit range of jitter estimate */
7316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (rec_max_delay < MIN_ISAC_MD)
7326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    rec_max_delay = MIN_ISAC_MD;
7346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else if (rec_max_delay > MAX_ISAC_MD)
7366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    rec_max_delay = MAX_ISAC_MD;
7386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return rec_max_delay;
7406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
7416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* get the bottle neck rate from here to far side, as estimated by far side */
7436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid
7446f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtcIsac_GetUplinkBandwidth(
7456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const BwEstimatorstr* bwest_str,
7466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    WebRtc_Word32*          bitRate)
7476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
7486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* limit range of bottle neck rate */
7496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (bwest_str->send_bw_avg < MIN_ISAC_BW)
7506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    *bitRate = MIN_ISAC_BW;
7526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else if (bwest_str->send_bw_avg > MAX_ISAC_BW)
7546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    *bitRate = MAX_ISAC_BW;
7566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
7586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    *bitRate = (WebRtc_Word32)(bwest_str->send_bw_avg);
7606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return;
7626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
7636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/* Returns the max delay value from the other side in ms */
7656f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtc_Word32
7666f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinWebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr *bwest_str)
7676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
7686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  WebRtc_Word32 send_max_delay;
7696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  send_max_delay = (WebRtc_Word32)(bwest_str->send_max_delay_avg);
7716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* limit range of jitter estimate */
7736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (send_max_delay < MIN_ISAC_MD)
7746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    send_max_delay = MIN_ISAC_MD;
7766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else if (send_max_delay > MAX_ISAC_MD)
7786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
7796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    send_max_delay = MAX_ISAC_MD;
7806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
7816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return send_max_delay;
7826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
7836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
7856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/*
7866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * update long-term average bitrate and amount of data in buffer
7876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * returns minimum payload size (bytes)
7886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */
7896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinint WebRtcIsac_GetMinBytes(
7906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    RateModel*         State,
7916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    int                StreamSize,    /* bytes in bitstream */
7926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const int          FrameSamples,  /* samples per frame */
7936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const double       BottleNeck,    /* bottle neck rate; excl headers (bps) */
7946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const double       DelayBuildUp,  /* max delay from bottleneck buffering (ms) */
7956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    enum ISACBandwidth bandwidth
7966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /*,WebRtc_Word16        frequentLargePackets*/)
7976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
7986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double MinRate = 0.0;
7996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int    MinBytes;
8006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double TransmissionTime;
8016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int    burstInterval = BURST_INTERVAL;
8026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
8036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // first 10 packets @ low rate, then INIT_BURST_LEN packets @
8046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // fixed rate of INIT_RATE bps
8056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (State->InitCounter > 0)
8066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
8076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (State->InitCounter-- <= INIT_BURST_LEN)
8086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
8096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if(bandwidth == isac8kHz)
8106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
8116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        MinRate = INIT_RATE_WB;
8126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
8136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      else
8146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
8156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        MinRate = INIT_RATE_SWB;
8166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
8176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
8186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else
8196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
8206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      MinRate = 0;
8216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
8226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
8236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
8246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
8256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    /* handle burst */
8266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (State->BurstCounter)
8276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
8286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if (State->StillBuffered < (1.0 - 1.0/BURST_LEN) * DelayBuildUp)
8296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
8306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        /* max bps derived from BottleNeck and DelayBuildUp values */
8316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        MinRate = (1.0 + (FS/1000) * DelayBuildUp /
8326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                   (double)(BURST_LEN * FrameSamples)) * BottleNeck;
8336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
8346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      else
8356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      {
8366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // max bps derived from StillBuffered and DelayBuildUp
8376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // values
8386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        MinRate = (1.0 + (FS/1000) * (DelayBuildUp -
8396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                      State->StillBuffered) / (double)FrameSamples) * BottleNeck;
8406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if (MinRate < 1.04 * BottleNeck)
8416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        {
8426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          MinRate = 1.04 * BottleNeck;
8436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
8446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
8456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      State->BurstCounter--;
8466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
8476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
8486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
8496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
8506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* convert rate from bits/second to bytes/packet */
8516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  MinBytes = (int) (MinRate * FrameSamples / (8.0 * FS));
8526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
8536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* StreamSize will be adjusted if less than MinBytes */
8546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (StreamSize < MinBytes)
8556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
8566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    StreamSize = MinBytes;
8576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
8586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
8596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* keep track of when bottle neck was last exceeded by at least 1% */
8606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (StreamSize * 8.0 * FS / FrameSamples > 1.01 * BottleNeck) {
8616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (State->PrevExceed) {
8626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      /* bottle_neck exceded twice in a row, decrease ExceedAgo */
8636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      State->ExceedAgo -= /*BURST_INTERVAL*/ burstInterval / (BURST_LEN - 1);
8646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if (State->ExceedAgo < 0)
8656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        State->ExceedAgo = 0;
8666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
8676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else
8686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
8696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      State->ExceedAgo += (FrameSamples * 1000) / FS; /* ms */
8706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      State->PrevExceed = 1;
8716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
8726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
8736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  else
8746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
8756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    State->PrevExceed = 0;
8766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    State->ExceedAgo += (FrameSamples * 1000) / FS;     /* ms */
8776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
8786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
8796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* set burst flag if bottle neck not exceeded for long time */
8806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if ((State->ExceedAgo > burstInterval) &&
8816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      (State->BurstCounter == 0))
8826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
8836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (State->PrevExceed)
8846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
8856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      State->BurstCounter = BURST_LEN - 1;
8866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
8876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else
8886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    {
8896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      State->BurstCounter = BURST_LEN;
8906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
8916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
8926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
8936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
8946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* Update buffer delay */
8956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck;  /* ms */
8966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->StillBuffered += TransmissionTime;
8976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->StillBuffered -= (FrameSamples * 1000) / FS;     /* ms */
8986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (State->StillBuffered < 0.0)
8996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  {
9006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    State->StillBuffered = 0.0;
9016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
9026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return MinBytes;
9046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
9056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/*
9086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin * update long-term average bitrate and amount of data in buffer
9096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin */
9106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_UpdateRateModel(
9116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    RateModel *State,
9126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    int StreamSize,                    /* bytes in bitstream */
9136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const int FrameSamples,            /* samples per frame */
9146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const double BottleNeck)        /* bottle neck rate; excl headers (bps) */
9156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
9166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double TransmissionTime;
9176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* avoid the initial "high-rate" burst */
9196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->InitCounter = 0;
9206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* Update buffer delay */
9226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck;  /* ms */
9236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->StillBuffered += TransmissionTime;
9246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->StillBuffered -= (FrameSamples * 1000) / FS;     /* ms */
9256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (State->StillBuffered < 0.0)
9266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    State->StillBuffered = 0.0;
9276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
9296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid WebRtcIsac_InitRateModel(
9326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    RateModel *State)
9336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
9346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->PrevExceed      = 0;                        /* boolean */
9356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->ExceedAgo       = 0;                        /* ms */
9366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->BurstCounter    = 0;                        /* packets */
9376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->InitCounter     = INIT_BURST_LEN + 10;    /* packets */
9386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  State->StillBuffered   = 1.0;                    /* ms */
9396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
9406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinint WebRtcIsac_GetNewFrameLength(
9426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    double bottle_neck,
9436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    int    current_framesamples)
9446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
9456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  int new_framesamples;
9466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const int Thld_20_30 = 20000;
9486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //const int Thld_30_20 = 30000;
9506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const int Thld_30_20 = 1000000;   // disable 20 ms frames
9516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const int Thld_30_60 = 18000;
9536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //const int Thld_30_60 = 0;      // disable 60 ms frames
9546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const int Thld_60_30 = 27000;
9566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  new_framesamples = current_framesamples;
9596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* find new framelength */
9616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  switch(current_framesamples) {
9626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case 320:
9636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if (bottle_neck < Thld_20_30)
9646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        new_framesamples = 480;
9656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      break;
9666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case 480:
9676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if (bottle_neck < Thld_30_60)
9686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        new_framesamples = 960;
9696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      else if (bottle_neck > Thld_30_20)
9706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        new_framesamples = 320;
9716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      break;
9726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case 960:
9736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if (bottle_neck >= Thld_60_30)
9746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        new_framesamples = 480;
9756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      break;
9766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
9776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return new_framesamples;
9796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
9806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkindouble WebRtcIsac_GetSnr(
9826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    double bottle_neck,
9836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    int    framesamples)
9846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin{
9856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  double s2nr;
9866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double a_20 = -30.0;
9886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double b_20 = 0.8;
9896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double c_20 = 0.0;
9906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double a_30 = -23.0;
9926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double b_30 = 0.48;
9936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double c_30 = 0.0;
9946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double a_60 = -23.0;
9966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double b_60 = 0.53;
9976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const double c_60 = 0.0;
9986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
9996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
10006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  /* find new SNR value */
10016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  switch(framesamples) {
10026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case 320:
10036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      s2nr = a_20 + b_20 * bottle_neck * 0.001 + c_20 * bottle_neck *
10046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          bottle_neck * 0.000001;
10056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      break;
10066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case 480:
10076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      s2nr = a_30 + b_30 * bottle_neck * 0.001 + c_30 * bottle_neck *
10086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          bottle_neck * 0.000001;
10096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      break;
10106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    case 960:
10116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      s2nr = a_60 + b_60 * bottle_neck * 0.001 + c_60 * bottle_neck *
10126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          bottle_neck * 0.000001;
10136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      break;
10146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    default:
10156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      s2nr = 0;
10166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
10176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
10186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return s2nr;
10196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
10206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
1021