1a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/*
2a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
4a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  Use of this source code is governed by a BSD-style license
5a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  that can be found in the LICENSE file in the root of the source
6a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  tree. An additional intellectual property rights grant can be found
7a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  in the file PATENTS.  All contributing project authors may
8a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  be found in the AUTHORS file in the root of the source tree.
9a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
10a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
11a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/*
12a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * bandwidth_estimator.c
13a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
14a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * This file contains the code for the Bandwidth Estimator designed
15a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * for iSAC.
16a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
17a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * NOTE! Castings needed for C55, do not remove!
18a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
19a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
20a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
21a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "bandwidth_estimator.h"
22a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "settings.h"
23a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
24a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
25a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* array of quantization levels for bottle neck info; Matlab code: */
26a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */
27a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word16 kQRateTable[12] = {
28a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  10000, 11115, 12355, 13733, 15265, 16967,
29a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  18860, 20963, 23301, 25900, 28789, 32000
30a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
31a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
32a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* 0.1 times the values in the table kQRateTable */
33a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* values are in Q16                                         */
34a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word32 KQRate01[12] = {
35a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  65536000,  72843264,  80969728,  90000589,  100040704, 111194931,
36a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  123600896, 137383117, 152705434, 169738240, 188671590, 209715200
37a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
38a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
39a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Bits per Bytes Seconds
40a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 8 bits/byte * 1000 msec/sec * 1/framelength (in msec)->bits/byte*sec
41a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * frame length will either be 30 or 60 msec. 8738 is 1/60 in Q19 and 1/30 in Q18
42a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * The following number is either in Q15 or Q14 depending on the current frame length */
43a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word32 kBitsByteSec = 4369000;
44a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
45a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Received header rate. First value is for 30 ms packets and second for 60 ms */
46a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word16 kRecHeaderRate[2] = {
47a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  9333, 4666
48a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
49a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
50a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Inverted minimum and maximum bandwidth in Q30.
51a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   minBwInv 30 ms, maxBwInv 30 ms,
52a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   minBwInv 60 ms, maxBwInv 69 ms
53a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin*/
54a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word32 kInvBandwidth[4] = {
55a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  55539, 25978,
56a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  73213, 29284
57a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
58a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
59a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Number of samples in 25 msec */
60a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word32 kSamplesIn25msec = 400;
61a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
62a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
63a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/****************************************************************************
64a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * WebRtcIsacfix_InitBandwidthEstimator(...)
65a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
66a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * This function initializes the struct for the bandwidth estimator
67a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
68a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Input/Output:
69a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - bweStr        : Struct containing bandwidth information.
70a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
71a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Return value            : 0
72a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
73a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word32 WebRtcIsacfix_InitBandwidthEstimator(BwEstimatorstr *bweStr)
74a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
75a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevFrameSizeMs       = INIT_FRAME_LEN;
76a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevRtpNumber         = 0;
77a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevSendTime          = 0;
78a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevArrivalTime       = 0;
79a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevRtpRate           = 1;
80a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->lastUpdate            = 0;
81a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->lastReduction         = 0;
82a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->countUpdates          = -9;
83a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
84a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* INIT_BN_EST = 20000
85a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   * INIT_BN_EST_Q7 = 2560000
86a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   * INIT_HDR_RATE = 4666
87a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   * INIT_REC_BN_EST_Q5 = 789312
88a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   *
89a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   * recBwInv = 1/(INIT_BN_EST + INIT_HDR_RATE) in Q30
90a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   * recBwAvg = INIT_BN_EST + INIT_HDR_RATE in Q5
91a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   */
92a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recBwInv              = 43531;
93a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recBw                 = INIT_BN_EST;
94a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recBwAvgQ             = INIT_BN_EST_Q7;
95a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recBwAvg              = INIT_REC_BN_EST_Q5;
96a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recJitter             = (WebRtc_Word32) 327680;   /* 10 in Q15 */
97a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recJitterShortTerm    = 0;
98a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recJitterShortTermAbs = (WebRtc_Word32) 40960;    /* 5 in Q13 */
99a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recMaxDelay           = (WebRtc_Word32) 10;
100a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recMaxDelayAvgQ       = (WebRtc_Word32) 5120;     /* 10 in Q9 */
101a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recHeaderRate         = INIT_HDR_RATE;
102a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->countRecPkts          = 0;
103a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->sendBwAvg             = INIT_BN_EST_Q7;
104a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->sendMaxDelayAvg       = (WebRtc_Word32) 5120;     /* 10 in Q9 */
105a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
106a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->countHighSpeedRec     = 0;
107a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->highSpeedRec          = 0;
108a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->countHighSpeedSent    = 0;
109a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->highSpeedSend         = 0;
110a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->inWaitPeriod          = 0;
111a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
112a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Find the inverse of the max bw and min bw in Q30
113a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   *  (1 / (MAX_ISAC_BW + INIT_HDR_RATE) in Q30
114a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   *  (1 / (MIN_ISAC_BW + INIT_HDR_RATE) in Q30
115a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin   */
116a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->maxBwInv              = kInvBandwidth[3];
117a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->minBwInv              = kInvBandwidth[2];
118a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
119a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return 0;
120a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
121a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
122a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/****************************************************************************
123a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * WebRtcIsacfix_UpdateUplinkBwImpl(...)
124a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
125a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * This function updates bottle neck rate received from other side in payload
126a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * and calculates a new bottle neck to send to the other side.
127a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
128a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Input/Output:
129a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - bweStr           : struct containing bandwidth information.
130a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - rtpNumber        : value from RTP packet, from NetEq
131a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - frameSize        : length of signal frame in ms, from iSAC decoder
132a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - sendTime         : value in RTP header giving send time in samples
133a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - arrivalTime      : value given by timeGetTime() time of arrival in
134a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *                           samples of packet from NetEq
135a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - pksize           : size of packet in bytes, from NetEq
136a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - Index            : integer (range 0...23) indicating bottle neck &
137a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *                           jitter as estimated by other side
138a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
139a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Return value            : 0 if everything went fine,
140a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *                           -1 otherwise
141a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
142a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word32 WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
143a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                               const WebRtc_UWord16 rtpNumber,
144a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                               const WebRtc_Word16  frameSize,
145a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                               const WebRtc_UWord32 sendTime,
146a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                               const WebRtc_UWord32 arrivalTime,
147a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                               const WebRtc_Word16  pksize,
148a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                               const WebRtc_UWord16 Index)
149a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
150a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord16  weight = 0;
151a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32  currBwInv = 0;
152a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord16  recRtpRate;
153a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32  arrTimeProj;
154a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32   arrTimeDiff;
155a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32   arrTimeNoise;
156a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32   arrTimeNoiseAbs;
157a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32   sendTimeDiff;
158a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
159a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 delayCorrFactor = DELAY_CORRECTION_MED;
160a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 lateDiff = 0;
161a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 immediateSet = 0;
162a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 frameSizeSampl;
163a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
164a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  temp;
165a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  msec;
166a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32 exponent;
167a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32 reductionFactor;
168a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32 numBytesInv;
169a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  sign;
170a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
171a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32 byteSecondsPerBit;
172a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32 tempLower;
173a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32 tempUpper;
174a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 recBwAvgInv;
175a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 numPktsExpected;
176a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
177a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 errCode;
178a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
179a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* UPDATE ESTIMATES FROM OTHER SIDE */
180a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
181a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* The function also checks if Index has a valid value */
182a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  errCode = WebRtcIsacfix_UpdateUplinkBwRec(bweStr, Index);
183a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (errCode <0) {
184a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    return(errCode);
185a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
186a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
187a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
188a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* UPDATE ESTIMATES ON THIS SIDE */
189a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
190a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Bits per second per byte * 1/30 or 1/60 */
191a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (frameSize == 60) {
192a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* If frameSize changed since last call, from 30 to 60, recalculate some values */
193a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) {
194a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->countUpdates = 10;
195a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->recHeaderRate = kRecHeaderRate[1];
196a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
197a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->maxBwInv = kInvBandwidth[3];
198a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->minBwInv = kInvBandwidth[2];
199a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate));
200a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
201a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
202a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* kBitsByteSec is in Q15 */
203a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    recRtpRate = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
204a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                                                     (WebRtc_Word32)pksize), 15) + bweStr->recHeaderRate;
205a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
206a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
207a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* If frameSize changed since last call, from 60 to 30, recalculate some values */
208a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) {
209a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->countUpdates = 10;
210a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->recHeaderRate = kRecHeaderRate[0];
211a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
212a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->maxBwInv = kInvBandwidth[1];
213a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->minBwInv = kInvBandwidth[0];
214a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate));
215a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
216a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
217a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* kBitsByteSec is in Q14 */
218a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    recRtpRate = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
219a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                                                      (WebRtc_Word32)pksize), 14) + bweStr->recHeaderRate;
220a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
221a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
222a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
223a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Check for timer wrap-around */
224a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (arrivalTime < bweStr->prevArrivalTime) {
225a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->prevArrivalTime = arrivalTime;
226a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->lastUpdate      = arrivalTime;
227a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->lastReduction   = arrivalTime + FS3;
228a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
229a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->countRecPkts      = 0;
230a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
231a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* store frame size */
232a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->prevFrameSizeMs = frameSize;
233a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
234a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* store far-side transmission rate */
235a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->prevRtpRate = recRtpRate;
236a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
237a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* store far-side RTP time stamp */
238a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->prevRtpNumber = rtpNumber;
239a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
240a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    return 0;
241a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
242a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
243a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->countRecPkts++;
244a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
245a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Calculate framesize in msec */
246a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  frameSizeSampl = WEBRTC_SPL_MUL_16_16((WebRtc_Word16)SAMPLES_PER_MSEC, frameSize);
247a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
248a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Check that it's not one of the first 9 packets */
249a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if ( bweStr->countUpdates > 0 ) {
250a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
251a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* Stay in Wait Period for 1.5 seconds (no updates in wait period) */
252a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if(bweStr->inWaitPeriod) {
253a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if ((arrivalTime - bweStr->startWaitPeriod)> FS_1_HALF) {
254a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->inWaitPeriod = 0;
255a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
256a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
257a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
258a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* If not been updated for a long time, reduce the BN estimate */
259a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
260a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* Check send time difference between this packet and previous received      */
261a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    sendTimeDiff = sendTime - bweStr->prevSendTime;
262a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (sendTimeDiff <= WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1)) {
263a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
264a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      /* Only update if 3 seconds has past since last update */
265a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if ((arrivalTime - bweStr->lastUpdate) > FS3) {
266a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
267a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Calculate expected number of received packets since last update */
268a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        numPktsExpected =  WEBRTC_SPL_UDIV(arrivalTime - bweStr->lastUpdate, frameSizeSampl);
269a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
270a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* If received number of packets is more than 90% of expected (922 = 0.9 in Q10): */
271a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* do the update, else not                                                        */
272a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if(WEBRTC_SPL_LSHIFT_W32(bweStr->countRecPkts, 10)  > WEBRTC_SPL_MUL_16_16(922, numPktsExpected)) {
273a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* Q4 chosen to approx dividing by 16 */
274a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          msec = (arrivalTime - bweStr->lastReduction);
275a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
276a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* the number below represents 13 seconds, highly unlikely
277a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin             but to insure no overflow when reduction factor is multiplied by recBw inverse */
278a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          if (msec > 208000) {
279a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            msec = 208000;
280a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          }
281a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
282a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* Q20 2^(negative number: - 76/1048576) = .99995
283a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin             product is Q24 */
284a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          exponent = WEBRTC_SPL_UMUL(0x0000004C, msec);
285a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
286a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* do the approx with positive exponent so that value is actually rf^-1
287a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin             and multiply by bw inverse */
288a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          reductionFactor = WEBRTC_SPL_RSHIFT_U32(0x01000000 | (exponent & 0x00FFFFFF),
289a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                                  WEBRTC_SPL_RSHIFT_U32(exponent, 24));
290a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
291a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* reductionFactor in Q13 */
292a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          reductionFactor = WEBRTC_SPL_RSHIFT_U32(reductionFactor, 11);
293a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
294a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          if ( reductionFactor != 0 ) {
295a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            bweStr->recBwInv = WEBRTC_SPL_MUL((WebRtc_Word32)bweStr->recBwInv, (WebRtc_Word32)reductionFactor);
296a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            bweStr->recBwInv = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)bweStr->recBwInv, 13);
297a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
298a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          } else {
299a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            /* recBwInv = 1 / (INIT_BN_EST + INIT_HDR_RATE) in Q26 (Q30??)*/
300a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            bweStr->recBwInv = WEBRTC_SPL_DIV((1073741824 +
301a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                               WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)INIT_BN_EST + INIT_HDR_RATE), 1)), INIT_BN_EST + INIT_HDR_RATE);
302a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          }
303a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
304a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* reset time-since-update counter */
305a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          bweStr->lastReduction = arrivalTime;
306a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        } else {
307a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* Delay last reduction with 3 seconds */
308a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          bweStr->lastReduction = arrivalTime + FS3;
309a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          bweStr->lastUpdate    = arrivalTime;
310a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          bweStr->countRecPkts  = 0;
311a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
312a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
313a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    } else {
314a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->lastReduction = arrivalTime + FS3;
315a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->lastUpdate    = arrivalTime;
316a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->countRecPkts  = 0;
317a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
318a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
319a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
320a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /*   update only if previous packet was not lost */
321a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if ( rtpNumber == bweStr->prevRtpNumber + 1 ) {
322a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      arrTimeDiff = arrivalTime - bweStr->prevArrivalTime;
323a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
324a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if (!(bweStr->highSpeedSend && bweStr->highSpeedRec)) {
325a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (arrTimeDiff > frameSizeSampl) {
326a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          if (sendTimeDiff > 0) {
327a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            lateDiff = arrTimeDiff - sendTimeDiff -
328a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1);
329a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          } else {
330a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            lateDiff = arrTimeDiff - frameSizeSampl;
331a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          }
332a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
333a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* 8000 is 1/2 second (in samples at FS) */
334a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          if (lateDiff > 8000) {
335a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            delayCorrFactor = (WebRtc_Word32) DELAY_CORRECTION_MAX;
336a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            bweStr->inWaitPeriod = 1;
337a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            bweStr->startWaitPeriod = arrivalTime;
338a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            immediateSet = 1;
339a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          } else if (lateDiff > 5120) {
340a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            delayCorrFactor = (WebRtc_Word32) DELAY_CORRECTION_MED;
341a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            immediateSet = 1;
342a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            bweStr->inWaitPeriod = 1;
343a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            bweStr->startWaitPeriod = arrivalTime;
344a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          }
345a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
346a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
347a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
348a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if ((bweStr->prevRtpRate > WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) bweStr->recBwAvg, 5)) &&
349a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (recRtpRate > WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)bweStr->recBwAvg, 5)) &&
350a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          !bweStr->inWaitPeriod) {
351a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
352a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* test if still in initiation period and increment counter */
353a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (bweStr->countUpdates++ > 99) {
354a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* constant weight after initiation part, 0.01 in Q13 */
355a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          weight = (WebRtc_UWord16) 82;
356a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        } else {
357a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* weight decreases with number of updates, 1/countUpdates in Q13  */
358a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          weight = (WebRtc_UWord16) WebRtcSpl_DivW32W16(
359a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin              (WebRtc_Word32)(8192 + WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) bweStr->countUpdates, 1)),
360a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin              (WebRtc_Word16)bweStr->countUpdates);
361a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
362a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
363a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Bottle Neck Estimation */
364a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
365a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* limit outliers, if more than 25 ms too much */
366a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (arrTimeDiff > frameSizeSampl + kSamplesIn25msec) {
367a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          arrTimeDiff = frameSizeSampl + kSamplesIn25msec;
368a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
369a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
370a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* don't allow it to be less than frame rate - 10 ms */
371a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (arrTimeDiff < frameSizeSampl - FRAMESAMPLES_10ms) {
372a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          arrTimeDiff = frameSizeSampl - FRAMESAMPLES_10ms;
373a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
374a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
375a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* compute inverse receiving rate for last packet, in Q19 */
376a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        numBytesInv = (WebRtc_UWord16) WebRtcSpl_DivW32W16(
377a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            (WebRtc_Word32)(524288 + WEBRTC_SPL_RSHIFT_W32(((WebRtc_Word32)pksize + HEADER_SIZE), 1)),
378a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            (WebRtc_Word16)(pksize + HEADER_SIZE));
379a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
380a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* 8389 is  ~ 1/128000 in Q30 */
381a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        byteSecondsPerBit = WEBRTC_SPL_MUL_16_16(arrTimeDiff, 8389);
382a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
383a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* get upper N bits */
384a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        tempUpper = WEBRTC_SPL_RSHIFT_U32(byteSecondsPerBit, 15);
385a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
386a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* get lower 15 bits */
387a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        tempLower = byteSecondsPerBit & 0x00007FFF;
388a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
389a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        tempUpper = WEBRTC_SPL_MUL(tempUpper, numBytesInv);
390a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        tempLower = WEBRTC_SPL_MUL(tempLower, numBytesInv);
391a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        tempLower = WEBRTC_SPL_RSHIFT_U32(tempLower, 15);
392a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
393a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        currBwInv = tempUpper + tempLower;
394a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        currBwInv = WEBRTC_SPL_RSHIFT_U32(currBwInv, 4);
395a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
396a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Limit inv rate. Note that minBwInv > maxBwInv! */
397a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if(currBwInv < bweStr->maxBwInv) {
398a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          currBwInv = bweStr->maxBwInv;
399a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        } else if(currBwInv > bweStr->minBwInv) {
400a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          currBwInv = bweStr->minBwInv;
401a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
402a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
403a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* update bottle neck rate estimate */
404a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->recBwInv = WEBRTC_SPL_UMUL(weight, currBwInv) +
405a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            WEBRTC_SPL_UMUL((WebRtc_UWord32) 8192 - weight, bweStr->recBwInv);
406a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
407a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Shift back to Q30 from Q40 (actual used bits shouldn't be more than 27 based on minBwInv)
408a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin           up to 30 bits used with Q13 weight */
409a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->recBwInv = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwInv, 13);
410a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
411a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* reset time-since-update counter */
412a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->lastUpdate    = arrivalTime;
413a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->lastReduction = arrivalTime + FS3;
414a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->countRecPkts  = 0;
415a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
416a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* to save resolution compute the inverse of recBwAvg in Q26 by left shifting numerator to 2^31
417a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin           and NOT right shifting recBwAvg 5 bits to an integer
418a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin           At max 13 bits are used
419a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin           shift to Q5 */
420a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        recBwAvgInv = WEBRTC_SPL_UDIV((WebRtc_UWord32)(0x80000000 + WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 1)),
421a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                      bweStr->recBwAvg);
422a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
423a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Calculate Projected arrival time difference */
424a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
425a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* The numerator of the quotient can be 22 bits so right shift inv by 4 to avoid overflow
426a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin           result in Q22 */
427a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        arrTimeProj = WEBRTC_SPL_MUL((WebRtc_Word32)8000, recBwAvgInv);
428a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* shift to Q22 */
429a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 4);
430a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* complete calulation */
431a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        arrTimeProj = WEBRTC_SPL_MUL(((WebRtc_Word32)pksize + HEADER_SIZE), arrTimeProj);
432a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* shift to Q10 */
433a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 12);
434a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
435a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* difference between projected and actual arrival time differences */
436a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Q9 (only shift arrTimeDiff by 5 to simulate divide by 16 (need to revisit if change sampling rate) DH */
437a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) > (WebRtc_Word32)arrTimeProj) {
438a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          arrTimeNoise = WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) -  arrTimeProj;
439a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          sign = 1;
440a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        } else {
441a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          arrTimeNoise = arrTimeProj - WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6);
442a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          sign = -1;
443a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
444a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
445a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Q9 */
446a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        arrTimeNoiseAbs = arrTimeNoise;
447a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
448a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* long term averaged absolute jitter, Q15 */
449a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        weight = WEBRTC_SPL_RSHIFT_W32(weight, 3);
450a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->recJitter = WEBRTC_SPL_MUL(weight, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 5))
451a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            +  WEBRTC_SPL_MUL(1024 - weight, bweStr->recJitter);
452a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
453a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* remove the fractional portion */
454a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->recJitter = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitter, 10);
455a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
456a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Maximum jitter is 10 msec in Q15 */
457a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (bweStr->recJitter > (WebRtc_Word32)327680) {
458a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          bweStr->recJitter = (WebRtc_Word32)327680;
459a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
460a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
461a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* short term averaged absolute jitter */
462a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Calculation in Q13 products in Q23 */
463a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->recJitterShortTermAbs = WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 3)) +
464a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            WEBRTC_SPL_MUL(973, bweStr->recJitterShortTermAbs);
465a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->recJitterShortTermAbs = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTermAbs , 10);
466a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
467a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* short term averaged jitter */
468a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* Calculation in Q13 products in Q23 */
469a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bweStr->recJitterShortTerm = WEBRTC_SPL_MUL(205, WEBRTC_SPL_LSHIFT_W32(arrTimeNoise, 3)) * sign +
470a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            WEBRTC_SPL_MUL(3891, bweStr->recJitterShortTerm);
471a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
472a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (bweStr->recJitterShortTerm < 0) {
473a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          temp = -bweStr->recJitterShortTerm;
474a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          temp = WEBRTC_SPL_RSHIFT_W32(temp, 12);
475a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          bweStr->recJitterShortTerm = -temp;
476a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        } else {
477a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          bweStr->recJitterShortTerm = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 12);
478a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
479a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
480a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
481a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
482a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* reset time-since-update counter when receiving the first 9 packets */
483a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->lastUpdate    = arrivalTime;
484a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->lastReduction = arrivalTime + FS3;
485a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->countRecPkts  = 0;
486a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->countUpdates++;
487a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
488a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
489a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Limit to minimum or maximum bottle neck rate (in Q30) */
490a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (bweStr->recBwInv > bweStr->minBwInv) {
491a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recBwInv = bweStr->minBwInv;
492a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else if (bweStr->recBwInv < bweStr->maxBwInv) {
493a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recBwInv = bweStr->maxBwInv;
494a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
495a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
496a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
497a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* store frame length */
498a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevFrameSizeMs = frameSize;
499a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
500a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* store far-side transmission rate */
501a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevRtpRate = recRtpRate;
502a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
503a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* store far-side RTP time stamp */
504a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevRtpNumber = rtpNumber;
505a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
506a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Replace bweStr->recMaxDelay by the new value (atomic operation) */
507a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (bweStr->prevArrivalTime != 0xffffffff) {
508a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recMaxDelay = WEBRTC_SPL_MUL(3, bweStr->recJitter);
509a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
510a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
511a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* store arrival time stamp */
512a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevArrivalTime = arrivalTime;
513a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->prevSendTime = sendTime;
514a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
515a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Replace bweStr->recBw by the new value */
516a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recBw = WEBRTC_SPL_UDIV(1073741824, bweStr->recBwInv) - bweStr->recHeaderRate;
517a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
518a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (immediateSet) {
519a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* delay correction factor is in Q10 */
520a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recBw = WEBRTC_SPL_UMUL(delayCorrFactor, bweStr->recBw);
521a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recBw = WEBRTC_SPL_RSHIFT_U32(bweStr->recBw, 10);
522a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
523a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (bweStr->recBw < (WebRtc_Word32) MIN_ISAC_BW) {
524a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->recBw = (WebRtc_Word32) MIN_ISAC_BW;
525a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
526a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
527a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recBwAvg = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw + bweStr->recHeaderRate, 5);
528a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
529a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recBwAvgQ = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw, 7);
530a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
531a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recJitterShortTerm = 0;
532a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
533a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, bweStr->recBw + bweStr->recHeaderRate);
534a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
535a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    immediateSet = 0;
536a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
537a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
538a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
539a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return 0;
540a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
541a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
542a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* This function updates the send bottle neck rate                                                   */
543a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
544a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* returns 0 if everything went fine, -1 otherwise                                                   */
545a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word16 WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr,
546a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                              const WebRtc_Word16 Index)
547a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
548a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord16 RateInd;
549a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
550a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if ( (Index < 0) || (Index > 23) ) {
551a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
552a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
553a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
554a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* UPDATE ESTIMATES FROM OTHER SIDE */
555a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
556a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if ( Index > 11 ) {
557a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RateInd = Index - 12;
558a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* compute the jitter estimate as decoded on the other side in Q9 */
559a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MAX_ISAC_MD */
560a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
561a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)MAX_ISAC_MD, 9));
562a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
563a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
564a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
565a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RateInd = Index;
566a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* compute the jitter estimate as decoded on the other side in Q9 */
567a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MIN_ISAC_MD */
568a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
569a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)MIN_ISAC_MD,9));
570a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
571a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
572a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
573a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
574a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
575a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* compute the BN estimate as decoded on the other side */
576a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* sendBwAvg = 0.9 * sendBwAvg + 0.1 * kQRateTable[RateInd]; */
577a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->sendBwAvg = WEBRTC_SPL_UMUL(461, bweStr->sendBwAvg) +
578a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      WEBRTC_SPL_UMUL(51, WEBRTC_SPL_LSHIFT_U32(kQRateTable[RateInd], 7));
579a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->sendBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 9);
580a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
581a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
582a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7) > 28000 && !bweStr->highSpeedSend) {
583a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->countHighSpeedSent++;
584a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
585a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* approx 2 seconds with 30ms frames */
586a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (bweStr->countHighSpeedSent >= 66) {
587a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->highSpeedSend = 1;
588a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
589a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else if (!bweStr->highSpeedSend) {
590a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->countHighSpeedSent = 0;
591a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
592a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
593a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return 0;
594a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
595a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
596a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/****************************************************************************
597a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * WebRtcIsacfix_GetDownlinkBwIndexImpl(...)
598a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
599a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * This function calculates and returns the bandwidth/jitter estimation code
600a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * (integer 0...23) to put in the sending iSAC payload.
601a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
602a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Input:
603a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      - bweStr       : BWE struct
604a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
605a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Return:
606a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *      bandwith and jitter index (0..23)
607a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
608a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_UWord16 WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bweStr)
609a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
610a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  rate;
611a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  maxDelay;
612a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord16 rateInd;
613a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord16 maxDelayBit;
614a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  tempTerm1;
615a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  tempTerm2;
616a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  tempTermX;
617a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  tempTermY;
618a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  tempMin;
619a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32  tempMax;
620a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
621a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Get Rate Index */
622a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
623a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Get unquantized rate. Always returns 10000 <= rate <= 32000 */
624a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  rate = WebRtcIsacfix_GetDownlinkBandwidth(bweStr);
625a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
626a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Compute the averaged BN estimate on this side */
627a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
628a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* recBwAvg = 0.9 * recBwAvg + 0.1 * (rate + bweStr->recHeaderRate), 0.9 and 0.1 in Q9 */
629a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recBwAvg = WEBRTC_SPL_UMUL(922, bweStr->recBwAvg) +
630a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      WEBRTC_SPL_UMUL(102, WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)rate + bweStr->recHeaderRate, 5));
631a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 10);
632a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
633a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* find quantization index that gives the closest rate after averaging */
634a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (rateInd = 1; rateInd < 12; rateInd++) {
635a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (rate <= kQRateTable[rateInd]){
636a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      break;
637a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
638a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
639a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
640a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* find closest quantization index, and update quantized average by taking: */
641a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */
642a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
643a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* 0.9 times recBwAvgQ in Q16 */
644a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* 461/512 - 25/65536 =0.900009 */
645a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTerm1 = WEBRTC_SPL_MUL(bweStr->recBwAvgQ, 25);
646a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTerm1 = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 7);
647a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTermX = WEBRTC_SPL_UMUL(461, bweStr->recBwAvgQ) - tempTerm1;
648a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
649a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* rate in Q16 */
650a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTermY = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)rate, 16);
651a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
652a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* 0.1 * kQRateTable[rateInd] = KQRate01[rateInd] */
653a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTerm1 = tempTermX + KQRate01[rateInd] - tempTermY;
654a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTerm2 = tempTermY - tempTermX - KQRate01[rateInd-1];
655a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
656a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Compare (0.9 * recBwAvgQ + 0.1 * kQRateTable[rateInd] - rate) >
657a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin     (rate - 0.9 * recBwAvgQ - 0.1 * kQRateTable[rateInd-1]) */
658a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (tempTerm1  > tempTerm2) {
659a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    rateInd--;
660a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
661a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
662a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Update quantized average by taking:                  */
663a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */
664a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
665a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Add 0.1 times kQRateTable[rateInd], in Q16 */
666a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTermX += KQRate01[rateInd];
667a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
668a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Shift back to Q7 */
669a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bweStr->recBwAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTermX, 9);
670a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
671a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Count consecutive received bandwidth above 28000 kbps (28000 in Q7 = 3584000) */
672a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* If 66 high estimates in a row, set highSpeedRec to one */
673a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* 66 corresponds to ~2 seconds in 30 msec mode */
674a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if ((bweStr->recBwAvgQ > 3584000) && !bweStr->highSpeedRec) {
675a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->countHighSpeedRec++;
676a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (bweStr->countHighSpeedRec >= 66) {
677a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bweStr->highSpeedRec = 1;
678a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
679a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else if (!bweStr->highSpeedRec)    {
680a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->countHighSpeedRec = 0;
681a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
682a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
683a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Get Max Delay Bit */
684a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
685a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* get unquantized max delay */
686a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  maxDelay = WebRtcIsacfix_GetDownlinkMaxDelay(bweStr);
687a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
688a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Update quantized max delay average */
689a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempMax = 652800; /* MAX_ISAC_MD * 0.1 in Q18 */
690a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempMin = 130560; /* MIN_ISAC_MD * 0.1 in Q18 */
691a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTermX = WEBRTC_SPL_MUL((WebRtc_Word32)bweStr->recMaxDelayAvgQ, (WebRtc_Word32)461);
692a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTermY = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)maxDelay, 18);
693a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
694a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTerm1 = tempTermX + tempMax - tempTermY;
695a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tempTerm2 = tempTermY - tempTermX - tempMin;
696a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
697a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if ( tempTerm1 > tempTerm2) {
698a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    maxDelayBit = 0;
699a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tempTerm1 = tempTermX + tempMin;
700a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
701a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* update quantized average, shift back to Q9 */
702a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
703a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
704a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    maxDelayBit = 12;
705a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tempTerm1 =  tempTermX + tempMax;
706a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
707a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* update quantized average, shift back to Q9 */
708a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
709a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
710a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
711a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Return bandwitdh and jitter index (0..23) */
712a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return (WebRtc_UWord16)(rateInd + maxDelayBit);
713a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
714a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
715a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* get the bottle neck rate from far side to here, as estimated on this side */
716a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_UWord16 WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr)
717a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
718a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord32  recBw;
719a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32   jitter_sign; /* Q8 */
720a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32   bw_adjust;   /* Q16 */
721a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32   rec_jitter_short_term_abs_inv; /* Q18 */
722a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32   temp;
723a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
724a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Q18  rec jitter short term abs is in Q13, multiply it by 2^13 to save precision
725a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin     2^18 then needs to be shifted 13 bits to 2^31 */
726a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  rec_jitter_short_term_abs_inv = WEBRTC_SPL_UDIV(0x80000000, bweStr->recJitterShortTermAbs);
727a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
728a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Q27 = 9 + 18 */
729a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  jitter_sign = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 4), (WebRtc_Word32)rec_jitter_short_term_abs_inv);
730a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
731a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (jitter_sign < 0) {
732a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    temp = -jitter_sign;
733a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    temp = WEBRTC_SPL_RSHIFT_W32(temp, 19);
734a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    jitter_sign = -temp;
735a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
736a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    jitter_sign = WEBRTC_SPL_RSHIFT_W32(jitter_sign, 19);
737a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
738a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
739a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* adjust bw proportionally to negative average jitter sign */
740a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
741a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //Q8 -> Q16 .15 +.15 * jitter^2 first term is .15 in Q16 latter term is Q8*Q8*Q8
742a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //38 in Q8 ~.15 9830 in Q16 ~.15
743a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  temp = 9830  + WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL(38, WEBRTC_SPL_MUL(jitter_sign, jitter_sign))), 8);
744a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
745a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (jitter_sign < 0) {
746a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    temp = WEBRTC_SPL_MUL(jitter_sign, temp);
747a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    temp = -temp;
748a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    temp = WEBRTC_SPL_RSHIFT_W32(temp, 8);
749a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bw_adjust = (WebRtc_UWord32)65536 + temp; /* (1 << 16) + temp; */
750a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
751a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bw_adjust = (WebRtc_UWord32)65536 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(jitter_sign, temp), 8);/* (1 << 16) - ((jitter_sign * temp) >> 8); */
752a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
753a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
754a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //make sure following multiplication won't overflow
755a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //bw adjust now Q14
756a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  bw_adjust = WEBRTC_SPL_RSHIFT_W32(bw_adjust, 2);//see if good resolution is maintained
757a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
758a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* adjust Rate if jitter sign is mostly constant */
759a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  recBw = WEBRTC_SPL_UMUL(bweStr->recBw, bw_adjust);
760a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
761a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  recBw = WEBRTC_SPL_RSHIFT_W32(recBw, 14);
762a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
763a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* limit range of bottle neck rate */
764a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (recBw < MIN_ISAC_BW) {
765a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    recBw = MIN_ISAC_BW;
766a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else if (recBw > MAX_ISAC_BW) {
767a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    recBw = MAX_ISAC_BW;
768a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
769a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
770a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return  (WebRtc_UWord16) recBw;
771a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
772a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
773a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Returns the mmax delay (in ms) */
774a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word16 WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bweStr)
775a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
776a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 recMaxDelay;
777a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
778a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  recMaxDelay = (WebRtc_Word16)  WEBRTC_SPL_RSHIFT_W32(bweStr->recMaxDelay, 15);
779a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
780a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* limit range of jitter estimate */
781a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (recMaxDelay < MIN_ISAC_MD) {
782a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    recMaxDelay = MIN_ISAC_MD;
783a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else if (recMaxDelay > MAX_ISAC_MD) {
784a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    recMaxDelay = MAX_ISAC_MD;
785a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
786a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
787a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return recMaxDelay;
788a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
789a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
790a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* get the bottle neck rate from here to far side, as estimated by far side */
791a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word16 WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bweStr)
792a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
793a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 send_bw;
794a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
795a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  send_bw = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7);
796a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
797a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* limit range of bottle neck rate */
798a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (send_bw < MIN_ISAC_BW) {
799a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    send_bw = MIN_ISAC_BW;
800a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else if (send_bw > MAX_ISAC_BW) {
801a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    send_bw = MAX_ISAC_BW;
802a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
803a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
804a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return send_bw;
805a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
806a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
807a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
808a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
809a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Returns the max delay value from the other side in ms */
810a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word16 WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bweStr)
811a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
812a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 send_max_delay;
813a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
814a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  send_max_delay = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
815a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
816a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* limit range of jitter estimate */
817a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (send_max_delay < MIN_ISAC_MD) {
818a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    send_max_delay = MIN_ISAC_MD;
819a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else if (send_max_delay > MAX_ISAC_MD) {
820a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    send_max_delay = MAX_ISAC_MD;
821a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
822a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
823a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return send_max_delay;
824a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
825a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
826a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
827a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
828a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
829a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/*
830a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * update long-term average bitrate and amount of data in buffer
831a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * returns minimum payload size (bytes)
832a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
833a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_UWord16 WebRtcIsacfix_GetMinBytes(RateModel *State,
834a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         WebRtc_Word16 StreamSize,                    /* bytes in bitstream */
835a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         const WebRtc_Word16 FrameSamples,            /* samples per frame */
836a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         const WebRtc_Word16 BottleNeck,        /* bottle neck rate; excl headers (bps) */
837a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                         const WebRtc_Word16 DelayBuildUp)      /* max delay from bottle neck buffering (ms) */
838a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
839a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 MinRate = 0;
840a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_UWord16    MinBytes;
841a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 TransmissionTime;
842a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 inv_Q12;
843a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 den;
844a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
845a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
846a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* first 10 packets @ low rate, then INIT_BURST_LEN packets @ fixed rate of INIT_RATE bps */
847a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (State->InitCounter > 0) {
848a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (State->InitCounter-- <= INIT_BURST_LEN) {
849a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      MinRate = INIT_RATE;
850a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    } else {
851a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      MinRate = 0;
852a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
853a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
854a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* handle burst */
855a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (State->BurstCounter) {
856a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if (State->StillBuffered < WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL((512 - WEBRTC_SPL_DIV(512, BURST_LEN)), DelayBuildUp), 9)) {
857a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* max bps derived from BottleNeck and DelayBuildUp values */
858a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        inv_Q12 = WEBRTC_SPL_DIV(4096, WEBRTC_SPL_MUL(BURST_LEN, FrameSamples));
859a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp, inv_Q12), 3)), BottleNeck);
860a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      } else {
861a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        /* max bps derived from StillBuffered and DelayBuildUp values */
862a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        inv_Q12 = WEBRTC_SPL_DIV(4096, FrameSamples);
863a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (DelayBuildUp > State->StillBuffered) {
864a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp - State->StillBuffered, inv_Q12), 3)), BottleNeck);
865a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        } else if ((den = WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, (State->StillBuffered - DelayBuildUp))) >= FrameSamples) {
866a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          /* MinRate will be negative here */
867a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          MinRate = 0;
868a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        } else {
869a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          MinRate = WEBRTC_SPL_MUL((512 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(den, inv_Q12), 3)), BottleNeck);
870a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
871a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        //if (MinRate < 1.04 * BottleNeck)
872a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        //    MinRate = 1.04 * BottleNeck;
873a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        //Q9
874a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (MinRate < WEBRTC_SPL_MUL(532, BottleNeck)) {
875a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          MinRate += WEBRTC_SPL_MUL(22, BottleNeck);
876a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
877a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
878a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
879a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      State->BurstCounter--;
880a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
881a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
882a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
883a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
884a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* convert rate from bits/second to bytes/packet */
885a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //round and shift before conversion
886a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  MinRate += 256;
887a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  MinRate = WEBRTC_SPL_RSHIFT_W32(MinRate, 9);
888a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  MinBytes = (WebRtc_UWord16)WEBRTC_SPL_UDIV(WEBRTC_SPL_MUL(MinRate, FrameSamples), FS8);
889a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
890a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* StreamSize will be adjusted if less than MinBytes */
891a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (StreamSize < MinBytes) {
892a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    StreamSize = MinBytes;
893a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
894a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
895a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* keep track of when bottle neck was last exceeded by at least 1% */
896a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //517/512 ~ 1.01
897a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, FS8), FrameSamples) > (WEBRTC_SPL_MUL(517, BottleNeck) >> 9)) {
898a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (State->PrevExceed) {
899a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      /* bottle_neck exceded twice in a row, decrease ExceedAgo */
900a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      State->ExceedAgo -= WEBRTC_SPL_DIV(BURST_INTERVAL, BURST_LEN - 1);
901a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if (State->ExceedAgo < 0) {
902a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        State->ExceedAgo = 0;
903a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
904a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    } else {
905a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      State->ExceedAgo += (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);       /* ms */
906a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      State->PrevExceed = 1;
907a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
908a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
909a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    State->PrevExceed = 0;
910a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    State->ExceedAgo += (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);           /* ms */
911a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
912a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
913a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* set burst flag if bottle neck not exceeded for long time */
914a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if ((State->ExceedAgo > BURST_INTERVAL) && (State->BurstCounter == 0)) {
915a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (State->PrevExceed) {
916a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      State->BurstCounter = BURST_LEN - 1;
917a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    } else {
918a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      State->BurstCounter = BURST_LEN;
919a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
920a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
921a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
922a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
923a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Update buffer delay */
924a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  TransmissionTime = (WebRtc_Word16)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, 8000), BottleNeck);    /* ms */
925a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->StillBuffered += TransmissionTime;
926a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->StillBuffered -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);  //>>4 =  SAMPLES_PER_MSEC        /* ms */
927a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (State->StillBuffered < 0) {
928a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    State->StillBuffered = 0;
929a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
930a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
931a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (State->StillBuffered > 2000) {
932a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    State->StillBuffered = 2000;
933a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
934a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
935a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return MinBytes;
936a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
937a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
938a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
939a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/*
940a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * update long-term average bitrate and amount of data in buffer
941a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
942a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid WebRtcIsacfix_UpdateRateModel(RateModel *State,
943a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                   WebRtc_Word16 StreamSize,                    /* bytes in bitstream */
944a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                   const WebRtc_Word16 FrameSamples,            /* samples per frame */
945a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                                   const WebRtc_Word16 BottleNeck)        /* bottle neck rate; excl headers (bps) */
946a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
947a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 TransmissionTime;
948a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
949a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* avoid the initial "high-rate" burst */
950a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->InitCounter = 0;
951a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
952a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Update buffer delay */
953a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  TransmissionTime = (WebRtc_Word16)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(WEBRTC_SPL_MUL(StreamSize, 8), 1000), BottleNeck);    /* ms */
954a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->StillBuffered += TransmissionTime;
955a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->StillBuffered -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);            /* ms */
956a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (State->StillBuffered < 0) {
957a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    State->StillBuffered = 0;
958a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
959a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
960a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
961a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
962a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
963a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid WebRtcIsacfix_InitRateModel(RateModel *State)
964a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
965a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->PrevExceed      = 0;                        /* boolean */
966a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->ExceedAgo       = 0;                        /* ms */
967a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->BurstCounter    = 0;                        /* packets */
968a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->InitCounter     = INIT_BURST_LEN + 10;    /* packets */
969a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  State->StillBuffered   = 1;                    /* ms */
970a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
971a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
972a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
973a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
974a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
975a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
976a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word16 WebRtcIsacfix_GetNewFrameLength(WebRtc_Word16 bottle_neck, WebRtc_Word16 current_framesamples)
977a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
978a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 new_framesamples;
979a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
980a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  new_framesamples = current_framesamples;
981a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
982a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* find new framelength */
983a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  switch(current_framesamples) {
984a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    case 480:
985a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if (bottle_neck < Thld_30_60) {
986a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        new_framesamples = 960;
987a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
988a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      break;
989a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    case 960:
990a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if (bottle_neck >= Thld_60_30) {
991a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        new_framesamples = 480;
992a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
993a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      break;
994a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    default:
995a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      new_framesamples = -1; /* Error */
996a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
997a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
998a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return new_framesamples;
999a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
1000a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
1001a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word16 WebRtcIsacfix_GetSnr(WebRtc_Word16 bottle_neck, WebRtc_Word16 framesamples)
1002a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
1003a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 s2nr = 0;
1004a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
1005a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* find new SNR value */
1006a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //consider BottleNeck to be in Q10 ( * 1 in Q10)
1007a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  switch(framesamples) {
1008a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    case 480:
1009a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      /*s2nr = -1*(a_30 << 10) + ((b_30 * bottle_neck) >> 10);*/
1010a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      s2nr = -22500 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001;
1011a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      break;
1012a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    case 960:
1013a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      /*s2nr = -1*(a_60 << 10) + ((b_60 * bottle_neck) >> 10);*/
1014a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      s2nr = -22500 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001;
1015a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      break;
1016a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    default:
1017a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      s2nr = -1; /* Error */
1018a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
1019a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
1020a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return s2nr; //return in Q10
1021a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
1022a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
1023