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)) */ 27 static 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 */ 34 static 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 */ 43 static const WebRtc_Word32 kBitsByteSec = 4369000; 44 45 /* Received header rate. First value is for 30 ms packets and second for 60 ms */ 46 static 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 */ 54 static const WebRtc_Word32 kInvBandwidth[4] = { 55 55539, 25978, 56 73213, 29284 57 }; 58 59 /* Number of samples in 25 msec */ 60 static 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 */ 73 WebRtc_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 */ 142 WebRtc_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 */ 545 WebRtc_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 */ 608 WebRtc_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 */ 716 WebRtc_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) */ 774 WebRtc_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 */ 791 WebRtc_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 */ 810 WebRtc_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 */ 833 WebRtc_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 */ 942 void 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 963 void 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 976 WebRtc_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 1001 WebRtc_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