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