1 /* 2 * Copyright (c) 2012 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 * isac.c 13 * 14 * This C file contains the functions for the ISAC API 15 * 16 */ 17 18 #include "isac.h" 19 #include "bandwidth_estimator.h" 20 #include "crc.h" 21 #include "entropy_coding.h" 22 #include "codec.h" 23 #include "structs.h" 24 #include "signal_processing_library.h" 25 #include "lpc_shape_swb16_tables.h" 26 #include "os_specific_inline.h" 27 28 #include <stdio.h> 29 #include <string.h> 30 #include <stdlib.h> 31 #include <math.h> 32 33 #define BIT_MASK_DEC_INIT 0x0001 34 #define BIT_MASK_ENC_INIT 0x0002 35 36 #define LEN_CHECK_SUM_WORD8 4 37 #define MAX_NUM_LAYERS 10 38 39 40 /**************************************************************************** 41 * UpdatePayloadSizeLimit(...) 42 * 43 * Call this function to update the limit on the payload size. The limit on 44 * payload size might change i) if a user ''directly changes the limit by 45 * calling xxx_setMaxPayloadSize() or xxx_setMaxRate(), or ii) indirectly 46 * when bandwidth is changing. The latter might be the result of bandwidth 47 * adaptation, or direct change of the bottleneck in instantaneous mode. 48 * 49 * This function takes the current overall limit on payload, and translates it 50 * to the limits on lower and upper-band. If the codec is in wideband mode, 51 * then the overall limit and the limit on the lower-band is the same. 52 * Otherwise, a fraction of the limit should be allocated to lower-band 53 * leaving some room for the upper-band bit-stream. That is why an update 54 * of limit is required every time that the bandwidth is changing. 55 * 56 */ 57 static void UpdatePayloadSizeLimit(ISACMainStruct* instISAC) { 58 WebRtc_Word16 lim30MsPayloadBytes = WEBRTC_SPL_MIN( 59 (instISAC->maxPayloadSizeBytes), 60 (instISAC->maxRateBytesPer30Ms)); 61 WebRtc_Word16 lim60MsPayloadBytes = WEBRTC_SPL_MIN( 62 (instISAC->maxPayloadSizeBytes), 63 (instISAC->maxRateBytesPer30Ms << 1)); 64 65 /* The only time that iSAC will have 60 ms 66 * frame-size is when operating in wideband, so 67 * there is no upper-band bit-stream. */ 68 69 if (instISAC->bandwidthKHz == isac8kHz) { 70 /* At 8 kHz there is no upper-band bit-stream, 71 * therefore, the lower-band limit is the overall limit. */ 72 instISAC->instLB.ISACencLB_obj.payloadLimitBytes60 = 73 lim60MsPayloadBytes; 74 instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = 75 lim30MsPayloadBytes; 76 } else { 77 /* When in super-wideband, we only have 30 ms frames. 78 * Do a rate allocation for the given limit. */ 79 if (lim30MsPayloadBytes > 250) { 80 /* 4/5 to lower-band the rest for upper-band. */ 81 instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = 82 (lim30MsPayloadBytes << 2) / 5; 83 } else if (lim30MsPayloadBytes > 200) { 84 /* For the interval of 200 to 250 the share of 85 * upper-band linearly grows from 20 to 50. */ 86 instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = 87 (lim30MsPayloadBytes << 1) / 5 + 100; 88 } else { 89 /* Allocate only 20 for upper-band. */ 90 instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = 91 lim30MsPayloadBytes - 20; 92 } 93 instISAC->instUB.ISACencUB_obj.maxPayloadSizeBytes = 94 lim30MsPayloadBytes; 95 } 96 } 97 98 99 /**************************************************************************** 100 * UpdateBottleneck(...) 101 * 102 * This function updates the bottleneck only if the codec is operating in 103 * channel-adaptive mode. Furthermore, as the update of bottleneck might 104 * result in an update of bandwidth, therefore, the bottlenech should be 105 * updated just right before the first 10ms of a frame is pushed into encoder. 106 * 107 */ 108 static void UpdateBottleneck(ISACMainStruct* instISAC) { 109 /* Read the bottleneck from bandwidth estimator for the 110 * first 10 ms audio. This way, if there is a change 111 * in bandwidth, upper and lower-band will be in sync. */ 112 if ((instISAC->codingMode == 0) && 113 (instISAC->instLB.ISACencLB_obj.buffer_index == 0) && 114 (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) { 115 WebRtc_Word32 bottleneck; 116 WebRtcIsac_GetUplinkBandwidth(&(instISAC->bwestimator_obj), 117 &bottleneck); 118 119 /* Adding hysteresis when increasing signal bandwidth. */ 120 if ((instISAC->bandwidthKHz == isac8kHz) 121 && (bottleneck > 37000) 122 && (bottleneck < 41000)) { 123 bottleneck = 37000; 124 } 125 126 /* Switching from 12 kHz to 16 kHz is not allowed at this revision. 127 * If we let this happen, we have to take care of buffer_index and 128 * the last LPC vector. */ 129 if ((instISAC->bandwidthKHz != isac16kHz) && 130 (bottleneck > 46000)) { 131 bottleneck = 46000; 132 } 133 134 /* We might need a rate allocation. */ 135 if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 136 /* Wideband is the only choice we have here. */ 137 instISAC->instLB.ISACencLB_obj.bottleneck = 138 (bottleneck > 32000) ? 32000 : bottleneck; 139 instISAC->bandwidthKHz = isac8kHz; 140 } else { 141 /* Do the rate-allocation and get the new bandwidth. */ 142 enum ISACBandwidth bandwidth; 143 WebRtcIsac_RateAllocation(bottleneck, 144 &(instISAC->instLB.ISACencLB_obj.bottleneck), 145 &(instISAC->instUB.ISACencUB_obj.bottleneck), 146 &bandwidth); 147 if (bandwidth != isac8kHz) { 148 instISAC->instLB.ISACencLB_obj.new_framelength = 480; 149 } 150 if (bandwidth != instISAC->bandwidthKHz) { 151 /* Bandwidth is changing. */ 152 instISAC->bandwidthKHz = bandwidth; 153 UpdatePayloadSizeLimit(instISAC); 154 if (bandwidth == isac12kHz) { 155 instISAC->instLB.ISACencLB_obj.buffer_index = 0; 156 } 157 /* Currently we don't let the bandwidth to switch to 16 kHz 158 * if in adaptive mode. If we let this happen, we have to take 159 * care of buffer_index and the last LPC vector. */ 160 } 161 } 162 } 163 } 164 165 166 /**************************************************************************** 167 * GetSendBandwidthInfo(...) 168 * 169 * This is called to get the bandwidth info. This info is the bandwidth and 170 * the jitter of 'there-to-here' channel, estimated 'here.' These info 171 * is signaled in an in-band fashion to the other side. 172 * 173 * The call to the bandwidth estimator triggers a recursive averaging which 174 * has to be synchronized between encoder & decoder, therefore, the call to 175 * BWE should be once per packet. As the BWE info is inserted into bit-stream 176 * We need a valid info right before the encodeLB function is going to 177 * generate a bit-stream. That is when lower-band buffer has already 20ms 178 * of audio, and the 3rd block of 10ms is going to be injected into encoder. 179 * 180 * Inputs: 181 * - instISAC : iSAC instance. 182 * 183 * Outputs: 184 * - bandwidthIndex : an index which has to be encoded in 185 * lower-band bit-stream, indicating the 186 * bandwidth of there-to-here channel. 187 * - jitterInfo : this indicates if the jitter is high 188 * or low and it is encoded in upper-band 189 * bit-stream. 190 * 191 */ 192 static void GetSendBandwidthInfo(ISACMainStruct* instISAC, 193 WebRtc_Word16* bandwidthIndex, 194 WebRtc_Word16* jitterInfo) { 195 if ((instISAC->instLB.ISACencLB_obj.buffer_index == 196 (FRAMESAMPLES_10ms << 1)) && 197 (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) { 198 /* Bandwidth estimation and coding. */ 199 WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), 200 bandwidthIndex, jitterInfo, 201 instISAC->decoderSamplingRateKHz); 202 } 203 } 204 205 206 /**************************************************************************** 207 * WebRtcIsac_AssignSize(...) 208 * 209 * This function returns the size of the ISAC instance, so that the instance 210 * can be created out side iSAC. 211 * 212 * Output: 213 * - sizeinbytes : number of bytes needed to allocate for the 214 * instance. 215 * 216 * Return value : 0 - Ok 217 * -1 - Error 218 */ 219 WebRtc_Word16 WebRtcIsac_AssignSize(int* sizeInBytes) { 220 *sizeInBytes = sizeof(ISACMainStruct) * 2 / sizeof(WebRtc_Word16); 221 return 0; 222 } 223 224 225 /**************************************************************************** 226 * WebRtcIsac_Assign(...) 227 * 228 * This function assigns the memory already created to the ISAC instance. 229 * 230 * Input: 231 * - ISAC_main_inst : address of the pointer to the coder instance. 232 * - instISAC_Addr : the already allocated memory, where we put the 233 * iSAC structure. 234 * 235 * Return value : 0 - Ok 236 * -1 - Error 237 */ 238 WebRtc_Word16 WebRtcIsac_Assign(ISACStruct** ISAC_main_inst, 239 void* instISAC_Addr) { 240 if (instISAC_Addr != NULL) { 241 ISACMainStruct* instISAC = (ISACMainStruct*)instISAC_Addr; 242 instISAC->errorCode = 0; 243 instISAC->initFlag = 0; 244 245 /* Assign the address. */ 246 *ISAC_main_inst = (ISACStruct*)instISAC_Addr; 247 248 /* Default is wideband. */ 249 instISAC->encoderSamplingRateKHz = kIsacWideband; 250 instISAC->decoderSamplingRateKHz = kIsacWideband; 251 instISAC->bandwidthKHz = isac8kHz; 252 return 0; 253 } else { 254 return -1; 255 } 256 } 257 258 259 /**************************************************************************** 260 * WebRtcIsac_Create(...) 261 * 262 * This function creates an ISAC instance, which will contain the state 263 * information for one coding/decoding channel. 264 * 265 * Input: 266 * - ISAC_main_inst : address of the pointer to the coder instance. 267 * 268 * Return value : 0 - Ok 269 * -1 - Error 270 */ 271 WebRtc_Word16 WebRtcIsac_Create(ISACStruct** ISAC_main_inst) { 272 ISACMainStruct* instISAC; 273 274 instISAC = (ISACMainStruct*)WEBRTC_SPL_VNEW(ISACMainStruct, 1); 275 *ISAC_main_inst = (ISACStruct*)instISAC; 276 if (*ISAC_main_inst != NULL) { 277 instISAC->errorCode = 0; 278 instISAC->initFlag = 0; 279 /* Default is wideband. */ 280 instISAC->bandwidthKHz = isac8kHz; 281 instISAC->encoderSamplingRateKHz = kIsacWideband; 282 instISAC->decoderSamplingRateKHz = kIsacWideband; 283 return 0; 284 } else { 285 return -1; 286 } 287 } 288 289 290 /**************************************************************************** 291 * WebRtcIsac_Free(...) 292 * 293 * This function frees the ISAC instance created at the beginning. 294 * 295 * Input: 296 * - ISAC_main_inst : a ISAC instance. 297 * 298 * Return value : 0 - Ok 299 * -1 - Error 300 */ 301 WebRtc_Word16 WebRtcIsac_Free(ISACStruct* ISAC_main_inst) { 302 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 303 WEBRTC_SPL_FREE(instISAC); 304 return 0; 305 } 306 307 308 /**************************************************************************** 309 * EncoderInitLb(...) - internal function for initialization of 310 * Lower Band 311 * EncoderInitUb(...) - internal function for initialization of 312 * Upper Band 313 * WebRtcIsac_EncoderInit(...) - API function 314 * 315 * This function initializes a ISAC instance prior to the encoder calls. 316 * 317 * Input: 318 * - ISAC_main_inst : ISAC instance. 319 * - CodingMode : 0 -> Bit rate and frame length are automatically 320 * adjusted to available bandwidth on 321 * transmission channel, applicable just to 322 * wideband mode. 323 * 1 -> User sets a frame length and a target bit 324 * rate which is taken as the maximum 325 * short-term average bit rate. 326 * 327 * Return value : 0 - Ok 328 * -1 - Error 329 */ 330 static WebRtc_Word16 EncoderInitLb(ISACLBStruct* instLB, 331 WebRtc_Word16 codingMode, 332 enum IsacSamplingRate sampRate) { 333 WebRtc_Word16 statusInit = 0; 334 int k; 335 336 /* Init stream vector to zero */ 337 for (k = 0; k < STREAM_SIZE_MAX_60; k++) { 338 instLB->ISACencLB_obj.bitstr_obj.stream[k] = 0; 339 } 340 341 if ((codingMode == 1) || (sampRate == kIsacSuperWideband)) { 342 /* 30 ms frame-size if either in super-wideband or 343 * instantaneous mode (I-mode). */ 344 instLB->ISACencLB_obj.new_framelength = 480; 345 } else { 346 instLB->ISACencLB_obj.new_framelength = INITIAL_FRAMESAMPLES; 347 } 348 349 WebRtcIsac_InitMasking(&instLB->ISACencLB_obj.maskfiltstr_obj); 350 WebRtcIsac_InitPreFilterbank(&instLB->ISACencLB_obj.prefiltbankstr_obj); 351 WebRtcIsac_InitPitchFilter(&instLB->ISACencLB_obj.pitchfiltstr_obj); 352 WebRtcIsac_InitPitchAnalysis( 353 &instLB->ISACencLB_obj.pitchanalysisstr_obj); 354 355 instLB->ISACencLB_obj.buffer_index = 0; 356 instLB->ISACencLB_obj.frame_nb = 0; 357 /* Default for I-mode. */ 358 instLB->ISACencLB_obj.bottleneck = 32000; 359 instLB->ISACencLB_obj.current_framesamples = 0; 360 instLB->ISACencLB_obj.s2nr = 0; 361 instLB->ISACencLB_obj.payloadLimitBytes30 = STREAM_SIZE_MAX_30; 362 instLB->ISACencLB_obj.payloadLimitBytes60 = STREAM_SIZE_MAX_60; 363 instLB->ISACencLB_obj.maxPayloadBytes = STREAM_SIZE_MAX_60; 364 instLB->ISACencLB_obj.maxRateInBytes = STREAM_SIZE_MAX_30; 365 instLB->ISACencLB_obj.enforceFrameSize = 0; 366 /* Invalid value prevents getRedPayload to 367 run before encoder is called. */ 368 instLB->ISACencLB_obj.lastBWIdx = -1; 369 return statusInit; 370 } 371 372 static WebRtc_Word16 EncoderInitUb(ISACUBStruct* instUB, 373 WebRtc_Word16 bandwidth) { 374 WebRtc_Word16 statusInit = 0; 375 int k; 376 377 /* Init stream vector to zero. */ 378 for (k = 0; k < STREAM_SIZE_MAX_60; k++) { 379 instUB->ISACencUB_obj.bitstr_obj.stream[k] = 0; 380 } 381 382 WebRtcIsac_InitMasking(&instUB->ISACencUB_obj.maskfiltstr_obj); 383 WebRtcIsac_InitPreFilterbank(&instUB->ISACencUB_obj.prefiltbankstr_obj); 384 385 if (bandwidth == isac16kHz) { 386 instUB->ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES; 387 } else { 388 instUB->ISACencUB_obj.buffer_index = 0; 389 } 390 /* Default for I-mode. */ 391 instUB->ISACencUB_obj.bottleneck = 32000; 392 /* These store the limits for the wideband + super-wideband bit-stream. */ 393 instUB->ISACencUB_obj.maxPayloadSizeBytes = STREAM_SIZE_MAX_30 << 1; 394 /* This has to be updated after each lower-band encoding to guarantee 395 * a correct payload-limitation. */ 396 instUB->ISACencUB_obj.numBytesUsed = 0; 397 memset(instUB->ISACencUB_obj.data_buffer_float, 0, 398 (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES) * sizeof(float)); 399 400 memcpy(&(instUB->ISACencUB_obj.lastLPCVec), 401 WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER); 402 403 return statusInit; 404 } 405 406 407 WebRtc_Word16 WebRtcIsac_EncoderInit(ISACStruct* ISAC_main_inst, 408 WebRtc_Word16 codingMode) { 409 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 410 WebRtc_Word16 status; 411 412 if ((codingMode != 0) && (codingMode != 1)) { 413 instISAC->errorCode = ISAC_DISALLOWED_CODING_MODE; 414 return -1; 415 } 416 /* Default bottleneck. */ 417 instISAC->bottleneck = MAX_ISAC_BW; 418 419 if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 420 instISAC->bandwidthKHz = isac8kHz; 421 instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; 422 instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; 423 } else { 424 instISAC->bandwidthKHz = isac16kHz; 425 instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; 426 instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; 427 } 428 429 /* Channel-adaptive = 0; Instantaneous (Channel-independent) = 1. */ 430 instISAC->codingMode = codingMode; 431 432 WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, 433 instISAC->encoderSamplingRateKHz, 434 instISAC->decoderSamplingRateKHz); 435 436 WebRtcIsac_InitRateModel(&instISAC->rate_data_obj); 437 /* Default for I-mode. */ 438 instISAC->MaxDelay = 10.0; 439 440 status = EncoderInitLb(&instISAC->instLB, codingMode, 441 instISAC->encoderSamplingRateKHz); 442 if (status < 0) { 443 instISAC->errorCode = -status; 444 return -1; 445 } 446 447 if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 448 /* Initialize encoder filter-bank. */ 449 memset(instISAC->analysisFBState1, 0, 450 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); 451 memset(instISAC->analysisFBState2, 0, 452 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); 453 454 status = EncoderInitUb(&(instISAC->instUB), 455 instISAC->bandwidthKHz); 456 if (status < 0) { 457 instISAC->errorCode = -status; 458 return -1; 459 } 460 } 461 /* Initialization is successful, set the flag. */ 462 instISAC->initFlag |= BIT_MASK_ENC_INIT; 463 return 0; 464 } 465 466 467 /**************************************************************************** 468 * WebRtcIsac_Encode(...) 469 * 470 * This function encodes 10ms frame(s) and inserts it into a package. 471 * Input speech length has to be 160 samples (10ms). The encoder buffers those 472 * 10ms frames until it reaches the chosen Framesize (480 or 960 samples 473 * corresponding to 30 or 60 ms frames), and then proceeds to the encoding. 474 * 475 * Input: 476 * - ISAC_main_inst : ISAC instance. 477 * - speechIn : input speech vector. 478 * 479 * Output: 480 * - encoded : the encoded data vector 481 * 482 * Return value: 483 * : >0 - Length (in bytes) of coded data 484 * : 0 - The buffer didn't reach the chosen 485 * frameSize so it keeps buffering speech 486 * samples. 487 * : -1 - Error 488 */ 489 WebRtc_Word16 WebRtcIsac_Encode(ISACStruct* ISAC_main_inst, 490 const WebRtc_Word16* speechIn, 491 WebRtc_Word16* encoded) { 492 float inFrame[FRAMESAMPLES_10ms]; 493 WebRtc_Word16 speechInLB[FRAMESAMPLES_10ms]; 494 WebRtc_Word16 speechInUB[FRAMESAMPLES_10ms]; 495 WebRtc_Word16 streamLenLB = 0; 496 WebRtc_Word16 streamLenUB = 0; 497 WebRtc_Word16 streamLen = 0; 498 WebRtc_Word16 k = 0; 499 WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; 500 int garbageLen = 0; 501 WebRtc_Word32 bottleneck = 0; 502 WebRtc_Word16 bottleneckIdx = 0; 503 WebRtc_Word16 jitterInfo = 0; 504 505 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 506 ISACLBStruct* instLB = &(instISAC->instLB); 507 ISACUBStruct* instUB = &(instISAC->instUB); 508 509 /* Check if encoder initiated. */ 510 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 511 BIT_MASK_ENC_INIT) { 512 instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 513 return -1; 514 } 515 516 if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 517 WebRtcSpl_AnalysisQMF(speechIn, speechInLB, speechInUB, 518 instISAC->analysisFBState1, 519 instISAC->analysisFBState2); 520 521 /* Convert from fixed to floating point. */ 522 for (k = 0; k < FRAMESAMPLES_10ms; k++) { 523 inFrame[k] = (float)speechInLB[k]; 524 } 525 } else { 526 for (k = 0; k < FRAMESAMPLES_10ms; k++) { 527 inFrame[k] = (float) speechIn[k]; 528 } 529 } 530 531 /* Add some noise to avoid denormal numbers. */ 532 inFrame[0] += (float)1.23455334e-3; 533 inFrame[1] -= (float)2.04324239e-3; 534 inFrame[2] += (float)1.90854954e-3; 535 inFrame[9] += (float)1.84854878e-3; 536 537 /* This function will update the bottleneck if required. */ 538 UpdateBottleneck(instISAC); 539 540 /* Get the bandwith information which has to be sent to the other side. */ 541 GetSendBandwidthInfo(instISAC, &bottleneckIdx, &jitterInfo); 542 543 /* Encode lower-band. */ 544 streamLenLB = WebRtcIsac_EncodeLb(inFrame, &instLB->ISACencLB_obj, 545 instISAC->codingMode, bottleneckIdx); 546 if (streamLenLB < 0) { 547 return -1; 548 } 549 550 if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 551 instUB = &(instISAC->instUB); 552 553 /* Convert to float. */ 554 for (k = 0; k < FRAMESAMPLES_10ms; k++) { 555 inFrame[k] = (float) speechInUB[k]; 556 } 557 558 /* Add some noise to avoid denormal numbers. */ 559 inFrame[0] += (float)1.23455334e-3; 560 inFrame[1] -= (float)2.04324239e-3; 561 inFrame[2] += (float)1.90854954e-3; 562 inFrame[9] += (float)1.84854878e-3; 563 564 /* Tell to upper-band the number of bytes used so far. 565 * This is for payload limitation. */ 566 instUB->ISACencUB_obj.numBytesUsed = streamLenLB + 1 + 567 LEN_CHECK_SUM_WORD8; 568 /* Encode upper-band. */ 569 switch (instISAC->bandwidthKHz) { 570 case isac12kHz: { 571 streamLenUB = WebRtcIsac_EncodeUb12(inFrame, &instUB->ISACencUB_obj, 572 jitterInfo); 573 break; 574 } 575 case isac16kHz: { 576 streamLenUB = WebRtcIsac_EncodeUb16(inFrame, &instUB->ISACencUB_obj, 577 jitterInfo); 578 break; 579 } 580 case isac8kHz: { 581 streamLenUB = 0; 582 break; 583 } 584 } 585 586 if ((streamLenUB < 0) && (streamLenUB != -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) { 587 /* An error has happened but this is not the error due to a 588 * bit-stream larger than the limit. */ 589 return -1; 590 } 591 592 if (streamLenLB == 0) { 593 return 0; 594 } 595 596 /* One byte is allocated for the length. According to older decoders 597 so the length bit-stream plus one byte for size and 598 LEN_CHECK_SUM_WORD8 for the checksum should be less than or equal 599 to 255. */ 600 if ((streamLenUB > (255 - (LEN_CHECK_SUM_WORD8 + 1))) || 601 (streamLenUB == -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) { 602 /* We have got a too long bit-stream we skip the upper-band 603 * bit-stream for this frame. */ 604 streamLenUB = 0; 605 } 606 607 memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream, streamLenLB); 608 streamLen = streamLenLB; 609 if (streamLenUB > 0) { 610 ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)(streamLenUB + 1 + 611 LEN_CHECK_SUM_WORD8); 612 memcpy(&ptrEncodedUW8[streamLenLB + 1], 613 instUB->ISACencUB_obj.bitstr_obj.stream, streamLenUB); 614 streamLen += ptrEncodedUW8[streamLenLB]; 615 } else { 616 ptrEncodedUW8[streamLenLB] = 0; 617 } 618 } else { 619 if (streamLenLB == 0) { 620 return 0; 621 } 622 memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream, 623 streamLenLB); 624 streamLenUB = 0; 625 streamLen = streamLenLB; 626 } 627 628 /* Add Garbage if required. */ 629 WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj, &bottleneck); 630 if (instISAC->codingMode == 0) { 631 int minBytes; 632 int limit; 633 WebRtc_UWord8* ptrGarbage; 634 635 instISAC->MaxDelay = (double)WebRtcIsac_GetUplinkMaxDelay( 636 &instISAC->bwestimator_obj); 637 638 /* Update rate model and get minimum number of bytes in this packet. */ 639 minBytes = WebRtcIsac_GetMinBytes( 640 &(instISAC->rate_data_obj), streamLen, 641 instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck, 642 instISAC->MaxDelay, instISAC->bandwidthKHz); 643 644 /* Make sure MinBytes does not exceed packet size limit. */ 645 if (instISAC->bandwidthKHz == isac8kHz) { 646 if (instLB->ISACencLB_obj.current_framesamples == FRAMESAMPLES) { 647 limit = instLB->ISACencLB_obj.payloadLimitBytes30; 648 } else { 649 limit = instLB->ISACencLB_obj.payloadLimitBytes60; 650 } 651 } else { 652 limit = instUB->ISACencUB_obj.maxPayloadSizeBytes; 653 } 654 minBytes = (minBytes > limit) ? limit : minBytes; 655 656 /* Make sure we don't allow more than 255 bytes of garbage data. 657 * We store the length of the garbage data in 8 bits in the bitstream, 658 * 255 is the max garbage length we can signal using 8 bits. */ 659 if ((instISAC->bandwidthKHz == isac8kHz) || 660 (streamLenUB == 0)) { 661 ptrGarbage = &ptrEncodedUW8[streamLenLB]; 662 limit = streamLen + 255; 663 } else { 664 ptrGarbage = &ptrEncodedUW8[streamLenLB + 1 + streamLenUB]; 665 limit = streamLen + (255 - ptrEncodedUW8[streamLenLB]); 666 } 667 minBytes = (minBytes > limit) ? limit : minBytes; 668 669 garbageLen = (minBytes > streamLen) ? (minBytes - streamLen) : 0; 670 671 /* Save data for creation of multiple bit-streams. */ 672 /* If bit-stream too short then add garbage at the end. */ 673 if (garbageLen > 0) { 674 for (k = 0; k < garbageLen; k++) { 675 ptrGarbage[k] = (WebRtc_UWord8)(rand() & 0xFF); 676 } 677 /* For a correct length of the upper-band bit-stream together 678 * with the garbage. Garbage is embeded in upper-band bit-stream. 679 * That is the only way to preserve backward compatibility. */ 680 if ((instISAC->bandwidthKHz == isac8kHz) || 681 (streamLenUB == 0)) { 682 ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)garbageLen; 683 } else { 684 ptrEncodedUW8[streamLenLB] += (WebRtc_UWord8)garbageLen; 685 /* Write the length of the garbage at the end of the upper-band 686 * bit-stream, if exists. This helps for sanity check. */ 687 ptrEncodedUW8[streamLenLB + 1 + streamLenUB] = 688 (WebRtc_UWord8)garbageLen; 689 690 } 691 streamLen += garbageLen; 692 } 693 } else { 694 /* update rate model */ 695 WebRtcIsac_UpdateRateModel( 696 &instISAC->rate_data_obj, streamLen, 697 instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck); 698 garbageLen = 0; 699 } 700 701 /* Generate CRC if required. */ 702 if ((instISAC->bandwidthKHz != isac8kHz) && (streamLenUB > 0)) { 703 WebRtc_UWord32 crc; 704 705 WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])), 706 streamLenUB + garbageLen, &crc); 707 #ifndef WEBRTC_BIG_ENDIAN 708 for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { 709 ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = 710 (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); 711 } 712 #else 713 memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, 714 LEN_CHECK_SUM_WORD8); 715 #endif 716 } 717 return streamLen; 718 } 719 720 721 /****************************************************************************** 722 * WebRtcIsac_GetNewBitStream(...) 723 * 724 * This function returns encoded data, with the recieved bwe-index in the 725 * stream. If the rate is set to a value less than bottleneck of codec 726 * the new bistream will be re-encoded with the given target rate. 727 * It should always return a complete packet, i.e. only called once 728 * even for 60 msec frames. 729 * 730 * NOTE 1! This function does not write in the ISACStruct, it is not allowed. 731 * NOTE 3! Rates larger than the bottleneck of the codec will be limited 732 * to the current bottleneck. 733 * 734 * Input: 735 * - ISAC_main_inst : ISAC instance. 736 * - bweIndex : Index of bandwidth estimate to put in new 737 * bitstream 738 * - rate : target rate of the transcoder is bits/sec. 739 * Valid values are the accepted rate in iSAC, 740 * i.e. 10000 to 56000. 741 * 742 * Output: 743 * - encoded : The encoded data vector 744 * 745 * Return value : >0 - Length (in bytes) of coded data 746 * -1 - Error or called in SWB mode 747 * NOTE! No error code is written to 748 * the struct since it is only allowed to read 749 * the struct. 750 */ 751 WebRtc_Word16 WebRtcIsac_GetNewBitStream(ISACStruct* ISAC_main_inst, 752 WebRtc_Word16 bweIndex, 753 WebRtc_Word16 jitterInfo, 754 WebRtc_Word32 rate, 755 WebRtc_Word16* encoded, 756 WebRtc_Word16 isRCU) { 757 Bitstr iSACBitStreamInst; /* Local struct for bitstream handling */ 758 WebRtc_Word16 streamLenLB; 759 WebRtc_Word16 streamLenUB; 760 WebRtc_Word16 totalStreamLen; 761 double gain2; 762 double gain1; 763 float scale; 764 enum ISACBandwidth bandwidthKHz; 765 double rateLB; 766 double rateUB; 767 WebRtc_Word32 currentBN; 768 WebRtc_UWord8* encodedPtrUW8 = (WebRtc_UWord8*)encoded; 769 WebRtc_UWord32 crc; 770 #ifndef WEBRTC_BIG_ENDIAN 771 WebRtc_Word16 k; 772 #endif 773 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 774 775 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 776 BIT_MASK_ENC_INIT) { 777 return -1; 778 } 779 780 /* Get the bottleneck of this iSAC and limit the 781 * given rate to the current bottleneck. */ 782 WebRtcIsac_GetUplinkBw(ISAC_main_inst, ¤tBN); 783 if (rate > currentBN) { 784 rate = currentBN; 785 } 786 787 if (WebRtcIsac_RateAllocation(rate, &rateLB, &rateUB, &bandwidthKHz) < 0) { 788 return -1; 789 } 790 791 /* Cannot transcode from 16 kHz to 12 kHz. */ 792 if ((bandwidthKHz == isac12kHz) && 793 (instISAC->bandwidthKHz == isac16kHz)) { 794 return -1; 795 } 796 797 /* A gain [dB] for the given rate. */ 798 gain1 = WebRtcIsac_GetSnr( 799 rateLB, instISAC->instLB.ISACencLB_obj.current_framesamples); 800 /* The gain [dB] of this iSAC. */ 801 gain2 = WebRtcIsac_GetSnr( 802 instISAC->instLB.ISACencLB_obj.bottleneck, 803 instISAC->instLB.ISACencLB_obj.current_framesamples); 804 805 /* Scale is the ratio of two gains in normal domain. */ 806 scale = (float)pow(10, (gain1 - gain2) / 20.0); 807 /* Change the scale if this is a RCU bit-stream. */ 808 scale = (isRCU) ? (scale * RCU_TRANSCODING_SCALE) : scale; 809 810 streamLenLB = WebRtcIsac_EncodeStoredDataLb( 811 &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, 812 &iSACBitStreamInst, bweIndex, scale); 813 814 if (streamLenLB < 0) { 815 return -1; 816 } 817 818 /* Convert from bytes to WebRtc_Word16. */ 819 memcpy(encoded, iSACBitStreamInst.stream, streamLenLB); 820 821 if (bandwidthKHz == isac8kHz) { 822 return streamLenLB; 823 } 824 825 totalStreamLen = streamLenLB; 826 /* super-wideband is always at 30ms. 827 * These gains are in dB. 828 * Gain for the given rate. */ 829 gain1 = WebRtcIsac_GetSnr(rateUB, FRAMESAMPLES); 830 /* Gain of this iSAC */ 831 gain2 = WebRtcIsac_GetSnr(instISAC->instUB.ISACencUB_obj.bottleneck, 832 FRAMESAMPLES); 833 834 /* Scale is the ratio of two gains in normal domain. */ 835 scale = (float)pow(10, (gain1 - gain2) / 20.0); 836 837 /* Change the scale if this is a RCU bit-stream. */ 838 scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE_UB) : scale; 839 840 streamLenUB = WebRtcIsac_EncodeStoredDataUb( 841 &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj), 842 &iSACBitStreamInst, jitterInfo, scale, 843 instISAC->bandwidthKHz); 844 845 if (streamLenUB < 0) { 846 return -1; 847 } 848 849 if (streamLenUB + 1 + LEN_CHECK_SUM_WORD8 > 255) { 850 return streamLenLB; 851 } 852 853 totalStreamLen = streamLenLB + streamLenUB + 1 + LEN_CHECK_SUM_WORD8; 854 encodedPtrUW8[streamLenLB] = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; 855 856 memcpy(&encodedPtrUW8[streamLenLB + 1], iSACBitStreamInst.stream, 857 streamLenUB); 858 859 WebRtcIsac_GetCrc((WebRtc_Word16*)(&(encodedPtrUW8[streamLenLB + 1])), 860 streamLenUB, &crc); 861 #ifndef WEBRTC_BIG_ENDIAN 862 for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { 863 encodedPtrUW8[totalStreamLen - LEN_CHECK_SUM_WORD8 + k] = 864 (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); 865 } 866 #else 867 memcpy(&encodedPtrUW8[streamLenLB + streamLenUB + 1], &crc, 868 LEN_CHECK_SUM_WORD8); 869 #endif 870 return totalStreamLen; 871 } 872 873 874 /**************************************************************************** 875 * DecoderInitLb(...) - internal function for initialization of 876 * Lower Band 877 * DecoderInitUb(...) - internal function for initialization of 878 * Upper Band 879 * WebRtcIsac_DecoderInit(...) - API function 880 * 881 * This function initializes a ISAC instance prior to the decoder calls. 882 * 883 * Input: 884 * - ISAC_main_inst : ISAC instance. 885 * 886 * Return value 887 * : 0 - Ok 888 * -1 - Error 889 */ 890 static WebRtc_Word16 DecoderInitLb(ISACLBStruct* instISAC) { 891 int i; 892 /* Initialize stream vector to zero. */ 893 for (i = 0; i < STREAM_SIZE_MAX_60; i++) { 894 instISAC->ISACdecLB_obj.bitstr_obj.stream[i] = 0; 895 } 896 897 WebRtcIsac_InitMasking(&instISAC->ISACdecLB_obj.maskfiltstr_obj); 898 WebRtcIsac_InitPostFilterbank( 899 &instISAC->ISACdecLB_obj.postfiltbankstr_obj); 900 WebRtcIsac_InitPitchFilter(&instISAC->ISACdecLB_obj.pitchfiltstr_obj); 901 return 0; 902 } 903 904 static WebRtc_Word16 DecoderInitUb(ISACUBStruct* instISAC) { 905 int i; 906 /* Init stream vector to zero */ 907 for (i = 0; i < STREAM_SIZE_MAX_60; i++) { 908 instISAC->ISACdecUB_obj.bitstr_obj.stream[i] = 0; 909 } 910 911 WebRtcIsac_InitMasking(&instISAC->ISACdecUB_obj.maskfiltstr_obj); 912 WebRtcIsac_InitPostFilterbank( 913 &instISAC->ISACdecUB_obj.postfiltbankstr_obj); 914 return (0); 915 } 916 917 WebRtc_Word16 WebRtcIsac_DecoderInit(ISACStruct* ISAC_main_inst) { 918 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 919 920 if (DecoderInitLb(&instISAC->instLB) < 0) { 921 return -1; 922 } 923 if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) { 924 memset(instISAC->synthesisFBState1, 0, 925 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); 926 memset(instISAC->synthesisFBState2, 0, 927 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); 928 929 if (DecoderInitUb(&(instISAC->instUB)) < 0) { 930 return -1; 931 } 932 } 933 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != BIT_MASK_ENC_INIT) { 934 WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, 935 instISAC->encoderSamplingRateKHz, 936 instISAC->decoderSamplingRateKHz); 937 } 938 instISAC->initFlag |= BIT_MASK_DEC_INIT; 939 instISAC->resetFlag_8kHz = 0; 940 return 0; 941 } 942 943 944 /**************************************************************************** 945 * WebRtcIsac_UpdateBwEstimate(...) 946 * 947 * This function updates the estimate of the bandwidth. 948 * 949 * Input: 950 * - ISAC_main_inst : ISAC instance. 951 * - encoded : encoded ISAC frame(s). 952 * - packet_size : size of the packet. 953 * - rtp_seq_number : the RTP number of the packet. 954 * - arr_ts : the arrival time of the packet (from NetEq) 955 * in samples. 956 * 957 * Return value : 0 - Ok 958 * -1 - Error 959 */ 960 WebRtc_Word16 WebRtcIsac_UpdateBwEstimate(ISACStruct* ISAC_main_inst, 961 const WebRtc_UWord16* encoded, 962 WebRtc_Word32 packet_size, 963 WebRtc_UWord16 rtp_seq_number, 964 WebRtc_UWord32 send_ts, 965 WebRtc_UWord32 arr_ts) { 966 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 967 Bitstr streamdata; 968 #ifndef WEBRTC_BIG_ENDIAN 969 int k; 970 #endif 971 WebRtc_Word16 err; 972 973 /* Check if decoder initiated. */ 974 if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != BIT_MASK_DEC_INIT) { 975 instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; 976 return -1; 977 } 978 979 if (packet_size <= 0) { 980 /* Return error code if the packet length is null. */ 981 instISAC->errorCode = ISAC_EMPTY_PACKET; 982 return -1; 983 } 984 985 WebRtcIsac_ResetBitstream(&(streamdata)); 986 987 #ifndef WEBRTC_BIG_ENDIAN 988 for (k = 0; k < 10; k++) { 989 streamdata.stream[k] = (WebRtc_UWord8)((encoded[k >> 1] >> 990 ((k & 1) << 3)) & 0xFF); 991 } 992 #else 993 memcpy(streamdata.stream, encoded, 10); 994 #endif 995 996 err = WebRtcIsac_EstimateBandwidth(&instISAC->bwestimator_obj, &streamdata, 997 packet_size, rtp_seq_number, send_ts, 998 arr_ts, instISAC->encoderSamplingRateKHz, 999 instISAC->decoderSamplingRateKHz); 1000 if (err < 0) { 1001 /* Return error code if something went wrong. */ 1002 instISAC->errorCode = -err; 1003 return -1; 1004 } 1005 return 0; 1006 } 1007 1008 static WebRtc_Word16 Decode(ISACStruct* ISAC_main_inst, 1009 const WebRtc_UWord16* encoded, 1010 WebRtc_Word16 lenEncodedBytes, 1011 WebRtc_Word16* decoded, 1012 WebRtc_Word16* speechType, 1013 WebRtc_Word16 isRCUPayload) { 1014 /* Number of samples (480 or 960), output from decoder 1015 that were actually used in the encoder/decoder 1016 (determined on the fly). */ 1017 WebRtc_Word16 numSamplesLB; 1018 WebRtc_Word16 numSamplesUB; 1019 WebRtc_Word16 speechIdx; 1020 float outFrame[MAX_FRAMESAMPLES]; 1021 WebRtc_Word16 outFrameLB[MAX_FRAMESAMPLES]; 1022 WebRtc_Word16 outFrameUB[MAX_FRAMESAMPLES]; 1023 WebRtc_Word16 numDecodedBytesLB; 1024 WebRtc_Word16 numDecodedBytesUB; 1025 WebRtc_Word16 lenEncodedLBBytes; 1026 WebRtc_Word16 validChecksum = 1; 1027 WebRtc_Word16 k; 1028 WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; 1029 WebRtc_UWord16 numLayer; 1030 WebRtc_Word16 totSizeBytes; 1031 WebRtc_Word16 err; 1032 1033 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1034 ISACUBDecStruct* decInstUB = &(instISAC->instUB.ISACdecUB_obj); 1035 ISACLBDecStruct* decInstLB = &(instISAC->instLB.ISACdecLB_obj); 1036 1037 /* Check if decoder initiated. */ 1038 if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != 1039 BIT_MASK_DEC_INIT) { 1040 instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; 1041 return -1; 1042 } 1043 1044 if (lenEncodedBytes <= 0) { 1045 /* return error code if the packet length is null. */ 1046 instISAC->errorCode = ISAC_EMPTY_PACKET; 1047 return -1; 1048 } 1049 1050 /* The size of the encoded lower-band is bounded by 1051 * STREAM_SIZE_MAX. If a payload with the size larger than STREAM_SIZE_MAX 1052 * is received, it is not considered erroneous. */ 1053 lenEncodedLBBytes = (lenEncodedBytes > STREAM_SIZE_MAX) ? 1054 STREAM_SIZE_MAX : lenEncodedBytes; 1055 1056 /* Copy to lower-band bit-stream structure. */ 1057 memcpy(instISAC->instLB.ISACdecLB_obj.bitstr_obj.stream, ptrEncodedUW8, 1058 lenEncodedLBBytes); 1059 1060 /* Regardless of that the current codec is setup to work in 1061 * wideband or super-wideband, the decoding of the lower-band 1062 * has to be performed. */ 1063 numDecodedBytesLB = WebRtcIsac_DecodeLb(outFrame, decInstLB, 1064 &numSamplesLB, isRCUPayload); 1065 1066 if ((numDecodedBytesLB < 0) || (numDecodedBytesLB > lenEncodedLBBytes) || 1067 (numSamplesLB > MAX_FRAMESAMPLES)) { 1068 instISAC->errorCode = ISAC_LENGTH_MISMATCH; 1069 return -1; 1070 } 1071 1072 /* Error Check, we accept multi-layer bit-stream This will limit number 1073 * of iterations of the while loop. Even without this the number 1074 * of iterations is limited. */ 1075 numLayer = 1; 1076 totSizeBytes = numDecodedBytesLB; 1077 while (totSizeBytes != lenEncodedBytes) { 1078 if ((totSizeBytes > lenEncodedBytes) || 1079 (ptrEncodedUW8[totSizeBytes] == 0) || 1080 (numLayer > MAX_NUM_LAYERS)) { 1081 instISAC->errorCode = ISAC_LENGTH_MISMATCH; 1082 return -1; 1083 } 1084 totSizeBytes += ptrEncodedUW8[totSizeBytes]; 1085 numLayer++; 1086 } 1087 1088 if (instISAC->decoderSamplingRateKHz == kIsacWideband) { 1089 for (k = 0; k < numSamplesLB; k++) { 1090 if (outFrame[k] > 32767) { 1091 decoded[k] = 32767; 1092 } else if (outFrame[k] < -32768) { 1093 decoded[k] = -32768; 1094 } else { 1095 decoded[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]); 1096 } 1097 } 1098 numSamplesUB = 0; 1099 } else { 1100 WebRtc_UWord32 crc; 1101 /* We don't accept larger than 30ms (480 samples at lower-band) 1102 * frame-size. */ 1103 for (k = 0; k < numSamplesLB; k++) { 1104 if (outFrame[k] > 32767) { 1105 outFrameLB[k] = 32767; 1106 } else if (outFrame[k] < -32768) { 1107 outFrameLB[k] = -32768; 1108 } else { 1109 outFrameLB[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]); 1110 } 1111 } 1112 1113 /* Check for possible error, and if upper-band stream exists. */ 1114 if (numDecodedBytesLB == lenEncodedBytes) { 1115 /* Decoding was successful. No super-wideband bit-stream exists. */ 1116 numSamplesUB = numSamplesLB; 1117 memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB); 1118 1119 /* Prepare for the potential increase of signal bandwidth. */ 1120 instISAC->resetFlag_8kHz = 2; 1121 } else { 1122 /* This includes the checksum and the bytes that stores the length. */ 1123 WebRtc_Word16 lenNextStream = ptrEncodedUW8[numDecodedBytesLB]; 1124 1125 /* Is this garbage or valid super-wideband bit-stream? 1126 * Check if checksum is valid. */ 1127 if (lenNextStream <= (LEN_CHECK_SUM_WORD8 + 1)) { 1128 /* Such a small second layer cannot be super-wideband layer. 1129 * It must be a short garbage. */ 1130 validChecksum = 0; 1131 } else { 1132 /* Run CRC to see if the checksum match. */ 1133 WebRtcIsac_GetCrc((WebRtc_Word16*)( 1134 &ptrEncodedUW8[numDecodedBytesLB + 1]), 1135 lenNextStream - LEN_CHECK_SUM_WORD8 - 1, &crc); 1136 1137 validChecksum = 1; 1138 for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { 1139 validChecksum &= (((crc >> (24 - k * 8)) & 0xFF) == 1140 ptrEncodedUW8[numDecodedBytesLB + lenNextStream - 1141 LEN_CHECK_SUM_WORD8 + k]); 1142 } 1143 } 1144 1145 if (!validChecksum) { 1146 /* This is a garbage, we have received a wideband 1147 * bit-stream with garbage. */ 1148 numSamplesUB = numSamplesLB; 1149 memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB); 1150 } else { 1151 /* A valid super-wideband biststream exists. */ 1152 enum ISACBandwidth bandwidthKHz; 1153 WebRtc_Word32 maxDelayBit; 1154 1155 /* If we have super-wideband bit-stream, we cannot 1156 * have 60 ms frame-size. */ 1157 if (numSamplesLB > FRAMESAMPLES) { 1158 instISAC->errorCode = ISAC_LENGTH_MISMATCH; 1159 return -1; 1160 } 1161 1162 /* The rest of the bit-stream contains the upper-band 1163 * bit-stream curently this is the only thing there, 1164 * however, we might add more layers. */ 1165 1166 /* Have to exclude one byte where the length is stored 1167 * and last 'LEN_CHECK_SUM_WORD8' bytes where the 1168 * checksum is stored. */ 1169 lenNextStream -= (LEN_CHECK_SUM_WORD8 + 1); 1170 1171 memcpy(decInstUB->bitstr_obj.stream, 1172 &ptrEncodedUW8[numDecodedBytesLB + 1], lenNextStream); 1173 1174 /* Reset bit-stream object, this is the first decoding. */ 1175 WebRtcIsac_ResetBitstream(&(decInstUB->bitstr_obj)); 1176 1177 /* Decode jitter information. */ 1178 err = WebRtcIsac_DecodeJitterInfo(&decInstUB->bitstr_obj, &maxDelayBit); 1179 if (err < 0) { 1180 instISAC->errorCode = -err; 1181 return -1; 1182 } 1183 1184 /* Update jitter info which is in the upper-band bit-stream 1185 * only if the encoder is in super-wideband. Otherwise, 1186 * the jitter info is already embedded in bandwidth index 1187 * and has been updated. */ 1188 if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 1189 err = WebRtcIsac_UpdateUplinkJitter( 1190 &(instISAC->bwestimator_obj), maxDelayBit); 1191 if (err < 0) { 1192 instISAC->errorCode = -err; 1193 return -1; 1194 } 1195 } 1196 1197 /* Decode bandwidth information. */ 1198 err = WebRtcIsac_DecodeBandwidth(&decInstUB->bitstr_obj, 1199 &bandwidthKHz); 1200 if (err < 0) { 1201 instISAC->errorCode = -err; 1202 return -1; 1203 } 1204 1205 switch (bandwidthKHz) { 1206 case isac12kHz: { 1207 numDecodedBytesUB = WebRtcIsac_DecodeUb12(outFrame, decInstUB, 1208 isRCUPayload); 1209 1210 /* Hang-over for transient alleviation - 1211 * wait two frames to add the upper band going up from 8 kHz. */ 1212 if (instISAC->resetFlag_8kHz > 0) { 1213 if (instISAC->resetFlag_8kHz == 2) { 1214 /* Silence first and a half frame. */ 1215 memset(outFrame, 0, MAX_FRAMESAMPLES * 1216 sizeof(float)); 1217 } else { 1218 const float rampStep = 2.0f / MAX_FRAMESAMPLES; 1219 float rampVal = 0; 1220 memset(outFrame, 0, (MAX_FRAMESAMPLES >> 1) * 1221 sizeof(float)); 1222 1223 /* Ramp up second half of second frame. */ 1224 for (k = MAX_FRAMESAMPLES / 2; k < MAX_FRAMESAMPLES; k++) { 1225 outFrame[k] *= rampVal; 1226 rampVal += rampStep; 1227 } 1228 } 1229 instISAC->resetFlag_8kHz -= 1; 1230 } 1231 1232 break; 1233 } 1234 case isac16kHz: { 1235 numDecodedBytesUB = WebRtcIsac_DecodeUb16(outFrame, decInstUB, 1236 isRCUPayload); 1237 break; 1238 } 1239 default: 1240 return -1; 1241 } 1242 1243 /* It might be less due to garbage. */ 1244 if ((numDecodedBytesUB != lenNextStream) && 1245 (numDecodedBytesUB != (lenNextStream - 1246 ptrEncodedUW8[numDecodedBytesLB + 1 + numDecodedBytesUB]))) { 1247 instISAC->errorCode = ISAC_LENGTH_MISMATCH; 1248 return -1; 1249 } 1250 1251 /* If there is no error Upper-band always decodes 1252 * 30 ms (480 samples). */ 1253 numSamplesUB = FRAMESAMPLES; 1254 1255 /* Convert to W16. */ 1256 for (k = 0; k < numSamplesUB; k++) { 1257 if (outFrame[k] > 32767) { 1258 outFrameUB[k] = 32767; 1259 } else if (outFrame[k] < -32768) { 1260 outFrameUB[k] = -32768; 1261 } else { 1262 outFrameUB[k] = (WebRtc_Word16)WebRtcIsac_lrint( 1263 outFrame[k]); 1264 } 1265 } 1266 } 1267 } 1268 1269 speechIdx = 0; 1270 while (speechIdx < numSamplesLB) { 1271 WebRtcSpl_SynthesisQMF(&outFrameLB[speechIdx], &outFrameUB[speechIdx], 1272 &decoded[(speechIdx << 1)], 1273 instISAC->synthesisFBState1, 1274 instISAC->synthesisFBState2); 1275 1276 speechIdx += FRAMESAMPLES_10ms; 1277 } 1278 } 1279 *speechType = 0; 1280 return (numSamplesLB + numSamplesUB); 1281 } 1282 1283 1284 1285 1286 1287 1288 1289 /**************************************************************************** 1290 * WebRtcIsac_Decode(...) 1291 * 1292 * This function decodes a ISAC frame. Output speech length 1293 * will be a multiple of 480 samples: 480 or 960 samples, 1294 * depending on the frameSize (30 or 60 ms). 1295 * 1296 * Input: 1297 * - ISAC_main_inst : ISAC instance. 1298 * - encoded : encoded ISAC frame(s) 1299 * - len : bytes in encoded vector 1300 * 1301 * Output: 1302 * - decoded : The decoded vector 1303 * 1304 * Return value : >0 - number of samples in decoded vector 1305 * -1 - Error 1306 */ 1307 1308 WebRtc_Word16 WebRtcIsac_Decode(ISACStruct* ISAC_main_inst, 1309 const WebRtc_UWord16* encoded, 1310 WebRtc_Word16 lenEncodedBytes, 1311 WebRtc_Word16* decoded, 1312 WebRtc_Word16* speechType) { 1313 WebRtc_Word16 isRCUPayload = 0; 1314 return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded, 1315 speechType, isRCUPayload); 1316 } 1317 1318 /**************************************************************************** 1319 * WebRtcIsac_DecodeRcu(...) 1320 * 1321 * This function decodes a redundant (RCU) iSAC frame. Function is called in 1322 * NetEq with a stored RCU payload in case of packet loss. Output speech length 1323 * will be a multiple of 480 samples: 480 or 960 samples, 1324 * depending on the framesize (30 or 60 ms). 1325 * 1326 * Input: 1327 * - ISAC_main_inst : ISAC instance. 1328 * - encoded : encoded ISAC RCU frame(s) 1329 * - len : bytes in encoded vector 1330 * 1331 * Output: 1332 * - decoded : The decoded vector 1333 * 1334 * Return value : >0 - number of samples in decoded vector 1335 * -1 - Error 1336 */ 1337 1338 1339 1340 WebRtc_Word16 WebRtcIsac_DecodeRcu(ISACStruct* ISAC_main_inst, 1341 const WebRtc_UWord16* encoded, 1342 WebRtc_Word16 lenEncodedBytes, 1343 WebRtc_Word16* decoded, 1344 WebRtc_Word16* speechType) { 1345 WebRtc_Word16 isRCUPayload = 1; 1346 return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded, 1347 speechType, isRCUPayload); 1348 } 1349 1350 1351 /**************************************************************************** 1352 * WebRtcIsac_DecodePlc(...) 1353 * 1354 * This function conducts PLC for ISAC frame(s). Output speech length 1355 * will be a multiple of 480 samples: 480 or 960 samples, 1356 * depending on the frameSize (30 or 60 ms). 1357 * 1358 * Input: 1359 * - ISAC_main_inst : ISAC instance. 1360 * - noOfLostFrames : Number of PLC frames to produce 1361 * 1362 * Output: 1363 * - decoded : The decoded vector 1364 * 1365 * Return value : >0 - number of samples in decoded PLC vector 1366 * -1 - Error 1367 */ 1368 WebRtc_Word16 WebRtcIsac_DecodePlc(ISACStruct* ISAC_main_inst, 1369 WebRtc_Word16* decoded, 1370 WebRtc_Word16 noOfLostFrames) { 1371 WebRtc_Word16 numSamples = 0; 1372 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1373 1374 /* Limit number of frames to two = 60 millisecond. 1375 * Otherwise we exceed data vectors. */ 1376 if (noOfLostFrames > 2) { 1377 noOfLostFrames = 2; 1378 } 1379 1380 /* Get the number of samples per frame */ 1381 switch (instISAC->decoderSamplingRateKHz) { 1382 case kIsacWideband: { 1383 numSamples = 480 * noOfLostFrames; 1384 break; 1385 } 1386 case kIsacSuperWideband: { 1387 numSamples = 960 * noOfLostFrames; 1388 break; 1389 } 1390 } 1391 1392 /* Set output samples to zero. */ 1393 memset(decoded, 0, numSamples * sizeof(WebRtc_Word16)); 1394 return numSamples; 1395 } 1396 1397 1398 /**************************************************************************** 1399 * ControlLb(...) - Internal function for controlling Lower Band 1400 * ControlUb(...) - Internal function for controlling Upper Band 1401 * WebRtcIsac_Control(...) - API function 1402 * 1403 * This function sets the limit on the short-term average bit rate and the 1404 * frame length. Should be used only in Instantaneous mode. 1405 * 1406 * Input: 1407 * - ISAC_main_inst : ISAC instance. 1408 * - rate : limit on the short-term average bit rate, 1409 * in bits/second (between 10000 and 32000) 1410 * - frameSize : number of milliseconds per frame (30 or 60) 1411 * 1412 * Return value : 0 - ok 1413 * -1 - Error 1414 */ 1415 static WebRtc_Word16 ControlLb(ISACLBStruct* instISAC, double rate, 1416 WebRtc_Word16 frameSize) { 1417 if ((rate >= 10000) && (rate <= 32000)) { 1418 instISAC->ISACencLB_obj.bottleneck = rate; 1419 } else { 1420 return -ISAC_DISALLOWED_BOTTLENECK; 1421 } 1422 1423 if ((frameSize == 30) || (frameSize == 60)) { 1424 instISAC->ISACencLB_obj.new_framelength = (FS / 1000) * frameSize; 1425 } else { 1426 return -ISAC_DISALLOWED_FRAME_LENGTH; 1427 } 1428 1429 return 0; 1430 } 1431 1432 static WebRtc_Word16 ControlUb(ISACUBStruct* instISAC, double rate) { 1433 if ((rate >= 10000) && (rate <= 32000)) { 1434 instISAC->ISACencUB_obj.bottleneck = rate; 1435 } else { 1436 return -ISAC_DISALLOWED_BOTTLENECK; 1437 } 1438 return 0; 1439 } 1440 1441 WebRtc_Word16 WebRtcIsac_Control(ISACStruct* ISAC_main_inst, 1442 WebRtc_Word32 bottleneckBPS, 1443 WebRtc_Word16 frameSize) { 1444 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1445 WebRtc_Word16 status; 1446 double rateLB; 1447 double rateUB; 1448 enum ISACBandwidth bandwidthKHz; 1449 1450 if (instISAC->codingMode == 0) { 1451 /* In adaptive mode. */ 1452 instISAC->errorCode = ISAC_MODE_MISMATCH; 1453 return -1; 1454 } 1455 1456 /* Check if encoder initiated */ 1457 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 1458 BIT_MASK_ENC_INIT) { 1459 instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1460 return -1; 1461 } 1462 1463 if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 1464 /* If the sampling rate is 16kHz then bandwith should be 8kHz, 1465 * regardless of bottleneck. */ 1466 bandwidthKHz = isac8kHz; 1467 rateLB = (bottleneckBPS > 32000) ? 32000 : bottleneckBPS; 1468 rateUB = 0; 1469 } else { 1470 if (WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, 1471 &bandwidthKHz) < 0) { 1472 return -1; 1473 } 1474 } 1475 1476 if ((instISAC->encoderSamplingRateKHz == kIsacSuperWideband) && 1477 (frameSize != 30) && 1478 (bandwidthKHz != isac8kHz)) { 1479 /* Cannot have 60 ms in super-wideband. */ 1480 instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; 1481 return -1; 1482 } 1483 1484 status = ControlLb(&instISAC->instLB, rateLB, frameSize); 1485 if (status < 0) { 1486 instISAC->errorCode = -status; 1487 return -1; 1488 } 1489 if (bandwidthKHz != isac8kHz) { 1490 status = ControlUb(&(instISAC->instUB), rateUB); 1491 if (status < 0) { 1492 instISAC->errorCode = -status; 1493 return -1; 1494 } 1495 } 1496 1497 1498 /* Check if bandwidth is changing from wideband to super-wideband 1499 * then we have to synch data buffer of lower & upper-band. Also 1500 * clean up the upper-band data buffer. */ 1501 1502 if ((instISAC->bandwidthKHz == isac8kHz) && (bandwidthKHz != isac8kHz)) { 1503 memset(instISAC->instUB.ISACencUB_obj.data_buffer_float, 0, 1504 sizeof(float) * (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES)); 1505 1506 if (bandwidthKHz == isac12kHz) { 1507 instISAC->instUB.ISACencUB_obj.buffer_index = 1508 instISAC->instLB.ISACencLB_obj.buffer_index; 1509 } else { 1510 instISAC->instUB.ISACencUB_obj.buffer_index = 1511 LB_TOTAL_DELAY_SAMPLES + instISAC->instLB.ISACencLB_obj.buffer_index; 1512 1513 memcpy(&(instISAC->instUB.ISACencUB_obj.lastLPCVec), 1514 WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER); 1515 } 1516 } 1517 1518 /* Update the payload limit if the bandwidth is changing. */ 1519 if (instISAC->bandwidthKHz != bandwidthKHz) { 1520 instISAC->bandwidthKHz = bandwidthKHz; 1521 UpdatePayloadSizeLimit(instISAC); 1522 } 1523 instISAC->bottleneck = bottleneckBPS; 1524 return 0; 1525 } 1526 1527 1528 /**************************************************************************** 1529 * WebRtcIsac_ControlBwe(...) 1530 * 1531 * This function sets the initial values of bottleneck and frame-size if 1532 * iSAC is used in channel-adaptive mode. Through this API, users can 1533 * enforce a frame-size for all values of bottleneck. Then iSAC will not 1534 * automatically change the frame-size. 1535 * 1536 * 1537 * Input: 1538 * - ISAC_main_inst : ISAC instance. 1539 * - rateBPS : initial value of bottleneck in bits/second 1540 * 10000 <= rateBPS <= 32000 is accepted 1541 * For default bottleneck set rateBPS = 0 1542 * - frameSizeMs : number of milliseconds per frame (30 or 60) 1543 * - enforceFrameSize : 1 to enforce the given frame-size through out 1544 * the adaptation process, 0 to let iSAC change 1545 * the frame-size if required. 1546 * 1547 * Return value : 0 - ok 1548 * -1 - Error 1549 */ 1550 WebRtc_Word16 WebRtcIsac_ControlBwe(ISACStruct* ISAC_main_inst, 1551 WebRtc_Word32 bottleneckBPS, 1552 WebRtc_Word16 frameSizeMs, 1553 WebRtc_Word16 enforceFrameSize) { 1554 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1555 enum ISACBandwidth bandwidth; 1556 1557 /* Check if encoder initiated */ 1558 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 1559 BIT_MASK_ENC_INIT) { 1560 instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1561 return -1; 1562 } 1563 1564 /* Check that we are in channel-adaptive mode, otherwise, return (-1) */ 1565 if (instISAC->codingMode != 0) { 1566 instISAC->errorCode = ISAC_MODE_MISMATCH; 1567 return -1; 1568 } 1569 if ((frameSizeMs != 30) && 1570 (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) { 1571 return -1; 1572 } 1573 1574 /* Set structure variable if enforceFrameSize is set. ISAC will then 1575 * keep the chosen frame size. */ 1576 if (enforceFrameSize != 0) { 1577 instISAC->instLB.ISACencLB_obj.enforceFrameSize = 1; 1578 } else { 1579 instISAC->instLB.ISACencLB_obj.enforceFrameSize = 0; 1580 } 1581 1582 /* Set the initial rate. If the input value is zero then the default intial 1583 * rate is used. Otehrwise, values between 10 to 32 kbps are accepted. */ 1584 if (bottleneckBPS != 0) { 1585 double rateLB; 1586 double rateUB; 1587 if (WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, 1588 &bandwidth) < 0) { 1589 return -1; 1590 } 1591 instISAC->bwestimator_obj.send_bw_avg = (float)bottleneckBPS; 1592 instISAC->bandwidthKHz = bandwidth; 1593 } 1594 1595 /* Set the initial frame-size. If 'enforceFrameSize' is set, the frame-size 1596 * will not change */ 1597 if (frameSizeMs != 0) { 1598 if ((frameSizeMs == 30) || (frameSizeMs == 60)) { 1599 instISAC->instLB.ISACencLB_obj.new_framelength = (FS / 1000) * 1600 frameSizeMs; 1601 } else { 1602 instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; 1603 return -1; 1604 } 1605 } 1606 return 0; 1607 } 1608 1609 1610 /**************************************************************************** 1611 * WebRtcIsac_GetDownLinkBwIndex(...) 1612 * 1613 * This function returns index representing the Bandwidth estimate from 1614 * the other side to this side. 1615 * 1616 * Input: 1617 * - ISAC_main_inst : iSAC structure 1618 * 1619 * Output: 1620 * - bweIndex : Bandwidth estimate to transmit to other side. 1621 * 1622 */ 1623 WebRtc_Word16 WebRtcIsac_GetDownLinkBwIndex(ISACStruct* ISAC_main_inst, 1624 WebRtc_Word16* bweIndex, 1625 WebRtc_Word16* jitterInfo) { 1626 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1627 1628 /* Check if encoder initialized. */ 1629 if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != 1630 BIT_MASK_DEC_INIT) { 1631 instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1632 return -1; 1633 } 1634 1635 /* Call function to get Bandwidth Estimate. */ 1636 WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), bweIndex, 1637 jitterInfo, 1638 instISAC->decoderSamplingRateKHz); 1639 return 0; 1640 } 1641 1642 1643 /**************************************************************************** 1644 * WebRtcIsac_UpdateUplinkBw(...) 1645 * 1646 * This function takes an index representing the Bandwidth estimate from 1647 * this side to other side and updates BWE. 1648 * 1649 * Input: 1650 * - ISAC_main_inst : iSAC structure 1651 * - rateIndex : Bandwidth estimate from other side. 1652 * 1653 * Return value : 0 - ok 1654 * -1 - index out of range 1655 */ 1656 WebRtc_Word16 WebRtcIsac_UpdateUplinkBw(ISACStruct* ISAC_main_inst, 1657 WebRtc_Word16 bweIndex) { 1658 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1659 WebRtc_Word16 returnVal; 1660 1661 /* Check if encoder initiated. */ 1662 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 1663 BIT_MASK_ENC_INIT) { 1664 instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1665 return -1; 1666 } 1667 1668 /* Call function to get Bandwidth Estimate. */ 1669 returnVal = WebRtcIsac_UpdateUplinkBwImpl( 1670 &(instISAC->bwestimator_obj), bweIndex, 1671 instISAC->encoderSamplingRateKHz); 1672 1673 if (returnVal < 0) { 1674 instISAC->errorCode = -returnVal; 1675 return -1; 1676 } else { 1677 return 0; 1678 } 1679 } 1680 1681 1682 /**************************************************************************** 1683 * WebRtcIsac_ReadBwIndex(...) 1684 * 1685 * This function returns the index of the Bandwidth estimate from the 1686 * bit-stream. 1687 * 1688 * Input: 1689 * - encoded : Encoded bit-stream 1690 * 1691 * Output: 1692 * - frameLength : Length of frame in packet (in samples) 1693 * - bweIndex : Bandwidth estimate in bit-stream 1694 * 1695 */ 1696 WebRtc_Word16 WebRtcIsac_ReadBwIndex(const WebRtc_Word16* encoded, 1697 WebRtc_Word16* bweIndex) { 1698 Bitstr streamdata; 1699 #ifndef WEBRTC_BIG_ENDIAN 1700 int k; 1701 #endif 1702 WebRtc_Word16 err; 1703 1704 WebRtcIsac_ResetBitstream(&(streamdata)); 1705 1706 #ifndef WEBRTC_BIG_ENDIAN 1707 for (k = 0; k < 10; k++) { 1708 streamdata.stream[k] = (WebRtc_UWord8)((encoded[k >> 1] >> 1709 ((k & 1) << 3)) & 0xFF); 1710 } 1711 #else 1712 memcpy(streamdata.stream, encoded, 10); 1713 #endif 1714 1715 /* Decode frame length. */ 1716 err = WebRtcIsac_DecodeFrameLen(&streamdata, bweIndex); 1717 if (err < 0) { 1718 return err; 1719 } 1720 1721 /* Decode BW estimation. */ 1722 err = WebRtcIsac_DecodeSendBW(&streamdata, bweIndex); 1723 if (err < 0) { 1724 return err; 1725 } 1726 1727 return 0; 1728 } 1729 1730 1731 /**************************************************************************** 1732 * WebRtcIsac_ReadFrameLen(...) 1733 * 1734 * This function returns the length of the frame represented in the packet. 1735 * 1736 * Input: 1737 * - encoded : Encoded bitstream 1738 * 1739 * Output: 1740 * - frameLength : Length of frame in packet (in samples) 1741 * 1742 */ 1743 WebRtc_Word16 WebRtcIsac_ReadFrameLen(ISACStruct* ISAC_main_inst, 1744 const WebRtc_Word16* encoded, 1745 WebRtc_Word16* frameLength) { 1746 Bitstr streamdata; 1747 #ifndef WEBRTC_BIG_ENDIAN 1748 int k; 1749 #endif 1750 WebRtc_Word16 err; 1751 ISACMainStruct* instISAC; 1752 1753 WebRtcIsac_ResetBitstream(&(streamdata)); 1754 1755 #ifndef WEBRTC_BIG_ENDIAN 1756 for (k = 0; k < 10; k++) { 1757 streamdata.stream[k] = (WebRtc_UWord8)((encoded[k >> 1] >> 1758 ((k & 1) << 3)) & 0xFF); 1759 } 1760 #else 1761 memcpy(streamdata.stream, encoded, 10); 1762 #endif 1763 1764 /* Decode frame length. */ 1765 err = WebRtcIsac_DecodeFrameLen(&streamdata, frameLength); 1766 if (err < 0) { 1767 return -1; 1768 } 1769 instISAC = (ISACMainStruct*)ISAC_main_inst; 1770 1771 if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) { 1772 /* The decoded frame length indicates the number of samples in 1773 * lower-band in this case, multiply by 2 to get the total number 1774 * of samples. */ 1775 *frameLength <<= 1; 1776 } 1777 return 0; 1778 } 1779 1780 1781 /******************************************************************************* 1782 * WebRtcIsac_GetNewFrameLen(...) 1783 * 1784 * This function returns the frame length (in samples) of the next packet. 1785 * In the case of channel-adaptive mode, iSAC decides on its frame length based 1786 * on the estimated bottleneck, this AOI allows a user to prepare for the next 1787 * packet (at the encoder). 1788 * 1789 * The primary usage is in CE to make the iSAC works in channel-adaptive mode 1790 * 1791 * Input: 1792 * - ISAC_main_inst : iSAC struct 1793 * 1794 * Return Value : frame lenght in samples 1795 * 1796 */ 1797 WebRtc_Word16 WebRtcIsac_GetNewFrameLen(ISACStruct* ISAC_main_inst) { 1798 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1799 1800 /* Return new frame length. */ 1801 if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 1802 return (instISAC->instLB.ISACencLB_obj.new_framelength); 1803 } else { 1804 return ((instISAC->instLB.ISACencLB_obj.new_framelength) << 1); 1805 } 1806 } 1807 1808 1809 /**************************************************************************** 1810 * WebRtcIsac_GetErrorCode(...) 1811 * 1812 * This function can be used to check the error code of an iSAC instance. 1813 * When a function returns -1 an error code will be set for that instance. 1814 * The function below extracts the code of the last error that occurred in 1815 * the specified instance. 1816 * 1817 * Input: 1818 * - ISAC_main_inst : ISAC instance 1819 * 1820 * Return value : Error code 1821 */ 1822 WebRtc_Word16 WebRtcIsac_GetErrorCode(ISACStruct* ISAC_main_inst) { 1823 return ((ISACMainStruct*)ISAC_main_inst)->errorCode; 1824 } 1825 1826 1827 /**************************************************************************** 1828 * WebRtcIsac_GetUplinkBw(...) 1829 * 1830 * This function outputs the target bottleneck of the codec. In 1831 * channel-adaptive mode, the target bottleneck is specified through an in-band 1832 * signalling retrieved by bandwidth estimator. 1833 * In channel-independent, also called instantaneous mode, the target 1834 * bottleneck is provided to the encoder by calling xxx_control(...) (if 1835 * xxx_control is never called, the default values are used.). 1836 * Note that the output is the iSAC internal operating bottleneck which might 1837 * differ slightly from the one provided through xxx_control(). 1838 * 1839 * Input: 1840 * - ISAC_main_inst : iSAC instance 1841 * 1842 * Output: 1843 * - *bottleneck : bottleneck in bits/sec 1844 * 1845 * Return value : -1 if error happens 1846 * 0 bit-rates computed correctly. 1847 */ 1848 WebRtc_Word16 WebRtcIsac_GetUplinkBw(ISACStruct* ISAC_main_inst, 1849 WebRtc_Word32* bottleneck) { 1850 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1851 1852 if (instISAC->codingMode == 0) { 1853 /* We are in adaptive mode then get the bottleneck from BWE. */ 1854 *bottleneck = (WebRtc_Word32)instISAC->bwestimator_obj.send_bw_avg; 1855 } else { 1856 *bottleneck = instISAC->bottleneck; 1857 } 1858 1859 if ((*bottleneck > 32000) && (*bottleneck < 38000)) { 1860 *bottleneck = 32000; 1861 } else if ((*bottleneck > 45000) && (*bottleneck < 50000)) { 1862 *bottleneck = 45000; 1863 } else if (*bottleneck > 56000) { 1864 *bottleneck = 56000; 1865 } 1866 return 0; 1867 } 1868 1869 1870 /****************************************************************************** 1871 * WebRtcIsac_SetMaxPayloadSize(...) 1872 * 1873 * This function sets a limit for the maximum payload size of iSAC. The same 1874 * value is used both for 30 and 60 ms packets. If the encoder sampling rate 1875 * is 16 kHz the maximum payload size is between 120 and 400 bytes. If the 1876 * encoder sampling rate is 32 kHz the maximum payload size is between 120 1877 * and 600 bytes. 1878 * 1879 * --------------- 1880 * IMPORTANT NOTES 1881 * --------------- 1882 * The size of a packet is limited to the minimum of 'max-payload-size' and 1883 * 'max-rate.' For instance, let's assume the max-payload-size is set to 1884 * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps 1885 * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms 1886 * frame-size. Then a packet with a frame-size of 30 ms is limited to 150, 1887 * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to 1888 * 170 bytes, i.e. min(170, 300). 1889 * 1890 * Input: 1891 * - ISAC_main_inst : iSAC instance 1892 * - maxPayloadBytes : maximum size of the payload in bytes 1893 * valid values are between 100 and 400 bytes 1894 * if encoder sampling rate is 16 kHz. For 1895 * 32 kHz encoder sampling rate valid values 1896 * are between 100 and 600 bytes. 1897 * 1898 * Return value : 0 if successful 1899 * -1 if error happens 1900 */ 1901 WebRtc_Word16 WebRtcIsac_SetMaxPayloadSize(ISACStruct* ISAC_main_inst, 1902 WebRtc_Word16 maxPayloadBytes) { 1903 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1904 WebRtc_Word16 status = 0; 1905 1906 /* Check if encoder initiated */ 1907 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 1908 BIT_MASK_ENC_INIT) { 1909 instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1910 return -1; 1911 } 1912 1913 if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 1914 /* Sanity check. */ 1915 if (maxPayloadBytes < 120) { 1916 /* 'maxRate' is out of valid range 1917 * set to the acceptable value and return -1. */ 1918 maxPayloadBytes = 120; 1919 status = -1; 1920 } 1921 1922 /* sanity check */ 1923 if (maxPayloadBytes > STREAM_SIZE_MAX) { 1924 /* maxRate is out of valid range, 1925 * set to the acceptable value and return -1. */ 1926 maxPayloadBytes = STREAM_SIZE_MAX; 1927 status = -1; 1928 } 1929 } else { 1930 if (maxPayloadBytes < 120) { 1931 /* Max payload-size is out of valid range 1932 * set to the acceptable value and return -1. */ 1933 maxPayloadBytes = 120; 1934 status = -1; 1935 } 1936 if (maxPayloadBytes > STREAM_SIZE_MAX_60) { 1937 /* Max payload-size is out of valid range 1938 * set to the acceptable value and return -1. */ 1939 maxPayloadBytes = STREAM_SIZE_MAX_60; 1940 status = -1; 1941 } 1942 } 1943 instISAC->maxPayloadSizeBytes = maxPayloadBytes; 1944 UpdatePayloadSizeLimit(instISAC); 1945 return status; 1946 } 1947 1948 1949 /****************************************************************************** 1950 * WebRtcIsac_SetMaxRate(...) 1951 * 1952 * This function sets the maximum rate which the codec may not exceed for 1953 * any signal packet. The maximum rate is defined and payload-size per 1954 * frame-size in bits per second. 1955 * 1956 * The codec has a maximum rate of 53400 bits per second (200 bytes per 30 1957 * ms) if the encoder sampling rate is 16kHz, and 160 kbps (600 bytes/30 ms) 1958 * if the encoder sampling rate is 32 kHz. 1959 * 1960 * It is possible to set a maximum rate between 32000 and 53400 bits/sec 1961 * in wideband mode, and 32000 to 160000 bits/sec in super-wideband mode. 1962 * 1963 * --------------- 1964 * IMPORTANT NOTES 1965 * --------------- 1966 * The size of a packet is limited to the minimum of 'max-payload-size' and 1967 * 'max-rate.' For instance, let's assume the max-payload-size is set to 1968 * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps 1969 * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms 1970 * frame-size. Then a packet with a frame-size of 30 ms is limited to 150, 1971 * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to 1972 * 170 bytes, min(170, 300). 1973 * 1974 * Input: 1975 * - ISAC_main_inst : iSAC instance 1976 * - maxRate : maximum rate in bits per second, 1977 * valid values are 32000 to 53400 bits/sec in 1978 * wideband mode, and 32000 to 160000 bits/sec in 1979 * super-wideband mode. 1980 * 1981 * Return value : 0 if successful 1982 * -1 if error happens 1983 */ 1984 WebRtc_Word16 WebRtcIsac_SetMaxRate(ISACStruct* ISAC_main_inst, 1985 WebRtc_Word32 maxRate) { 1986 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1987 WebRtc_Word16 maxRateInBytesPer30Ms; 1988 WebRtc_Word16 status = 0; 1989 1990 /* check if encoder initiated */ 1991 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != BIT_MASK_ENC_INIT) { 1992 instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1993 return -1; 1994 } 1995 /* Calculate maximum number of bytes per 30 msec packets for the 1996 given maximum rate. Multiply with 30/1000 to get number of 1997 bits per 30 ms, divide by 8 to get number of bytes per 30 ms: 1998 maxRateInBytes = floor((maxRate * 30/1000) / 8); */ 1999 maxRateInBytesPer30Ms = (WebRtc_Word16)(maxRate * 3 / 800); 2000 2001 if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 2002 if (maxRate < 32000) { 2003 /* 'maxRate' is out of valid range. 2004 * Set to the acceptable value and return -1. */ 2005 maxRateInBytesPer30Ms = 120; 2006 status = -1; 2007 } 2008 2009 if (maxRate > 53400) { 2010 /* 'maxRate' is out of valid range. 2011 * Set to the acceptable value and return -1. */ 2012 maxRateInBytesPer30Ms = 200; 2013 status = -1; 2014 } 2015 } else { 2016 if (maxRateInBytesPer30Ms < 120) { 2017 /* 'maxRate' is out of valid range 2018 * Sset to the acceptable value and return -1. */ 2019 maxRateInBytesPer30Ms = 120; 2020 status = -1; 2021 } 2022 2023 if (maxRateInBytesPer30Ms > STREAM_SIZE_MAX) { 2024 /* 'maxRate' is out of valid range. 2025 * Set to the acceptable value and return -1. */ 2026 maxRateInBytesPer30Ms = STREAM_SIZE_MAX; 2027 status = -1; 2028 } 2029 } 2030 instISAC->maxRateBytesPer30Ms = maxRateInBytesPer30Ms; 2031 UpdatePayloadSizeLimit(instISAC); 2032 return status; 2033 } 2034 2035 2036 /**************************************************************************** 2037 * WebRtcIsac_GetRedPayload(...) 2038 * 2039 * This function populates "encoded" with the redundant payload of the recently 2040 * encodedframe. This function has to be called once that WebRtcIsac_Encode(...) 2041 * returns a positive value. Regardless of the frame-size this function will 2042 * be called only once after encoding is completed. The bit-stream is 2043 * targeted for 16000 bit/sec. 2044 * 2045 * Input: 2046 * - ISAC_main_inst : iSAC struct 2047 * 2048 * Output: 2049 * - encoded : the encoded data vector 2050 * 2051 * 2052 * Return value : >0 - Length (in bytes) of coded data 2053 * : -1 - Error 2054 */ 2055 WebRtc_Word16 WebRtcIsac_GetRedPayload(ISACStruct* ISAC_main_inst, 2056 WebRtc_Word16* encoded) { 2057 Bitstr iSACBitStreamInst; 2058 WebRtc_Word16 streamLenLB; 2059 WebRtc_Word16 streamLenUB; 2060 WebRtc_Word16 streamLen; 2061 WebRtc_Word16 totalLenUB; 2062 WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; 2063 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2064 #ifndef WEBRTC_BIG_ENDIAN 2065 int k; 2066 #endif 2067 2068 if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 2069 BIT_MASK_ENC_INIT) { 2070 instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 2071 } 2072 2073 WebRtcIsac_ResetBitstream(&(iSACBitStreamInst)); 2074 2075 streamLenLB = WebRtcIsac_EncodeStoredDataLb( 2076 &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, 2077 &iSACBitStreamInst, 2078 instISAC->instLB.ISACencLB_obj.lastBWIdx, 2079 RCU_TRANSCODING_SCALE); 2080 if (streamLenLB < 0) { 2081 return -1; 2082 } 2083 2084 /* convert from bytes to WebRtc_Word16. */ 2085 memcpy(ptrEncodedUW8, iSACBitStreamInst.stream, streamLenLB); 2086 streamLen = streamLenLB; 2087 if (instISAC->bandwidthKHz == isac8kHz) { 2088 return streamLenLB; 2089 } 2090 2091 streamLenUB = WebRtcIsac_GetRedPayloadUb( 2092 &instISAC->instUB.ISACencUB_obj.SaveEnc_obj, 2093 &iSACBitStreamInst, instISAC->bandwidthKHz); 2094 if (streamLenUB < 0) { 2095 /* An error has happened but this is not the error due to a 2096 * bit-stream larger than the limit. */ 2097 return -1; 2098 } 2099 2100 /* We have one byte to write the total length of the upper-band. 2101 * The length includes the bit-stream length, check-sum and the 2102 * single byte where the length is written to. This is according to 2103 * iSAC wideband and how the "garbage" is dealt. */ 2104 totalLenUB = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; 2105 if (totalLenUB > 255) { 2106 streamLenUB = 0; 2107 } 2108 2109 /* Generate CRC if required. */ 2110 if ((instISAC->bandwidthKHz != isac8kHz) && 2111 (streamLenUB > 0)) { 2112 WebRtc_UWord32 crc; 2113 streamLen += totalLenUB; 2114 ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)totalLenUB; 2115 memcpy(&ptrEncodedUW8[streamLenLB + 1], iSACBitStreamInst.stream, 2116 streamLenUB); 2117 2118 WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])), 2119 streamLenUB, &crc); 2120 #ifndef WEBRTC_BIG_ENDIAN 2121 for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { 2122 ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = 2123 (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); 2124 } 2125 #else 2126 memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, 2127 LEN_CHECK_SUM_WORD8); 2128 #endif 2129 } 2130 return streamLen; 2131 } 2132 2133 2134 /**************************************************************************** 2135 * WebRtcIsac_version(...) 2136 * 2137 * This function returns the version number. 2138 * 2139 * Output: 2140 * - version : Pointer to character string 2141 * 2142 */ 2143 void WebRtcIsac_version(char* version) { 2144 strcpy(version, "4.3.0"); 2145 } 2146 2147 2148 /****************************************************************************** 2149 * WebRtcIsac_SetEncSampRate() 2150 * This function sets the sampling rate of the encoder. Initialization of the 2151 * encoder WILL NOT overwrite the sampling rate of the encoder. The default 2152 * value is 16 kHz which is set when the instance is created. The encoding-mode 2153 * and the bottleneck remain unchanged by this call, however, the maximum rate 2154 * and maximum payload-size will be reset to their default values. 2155 * 2156 * Input: 2157 * - ISAC_main_inst : iSAC instance 2158 * - sampRate : enumerator specifying the sampling rate. 2159 * 2160 * Return value : 0 if successful 2161 * -1 if failed. 2162 */ 2163 WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, 2164 enum IsacSamplingRate sampRate) { 2165 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2166 2167 if ((sampRate != kIsacWideband) && 2168 (sampRate != kIsacSuperWideband)) { 2169 /* Sampling Frequency is not supported. */ 2170 instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; 2171 return -1; 2172 } else if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 2173 BIT_MASK_ENC_INIT) { 2174 if (sampRate == kIsacWideband) { 2175 instISAC->bandwidthKHz = isac8kHz; 2176 } else { 2177 instISAC->bandwidthKHz = isac16kHz; 2178 } 2179 instISAC->encoderSamplingRateKHz = sampRate; 2180 return 0; 2181 } else { 2182 ISACUBStruct* instUB = &(instISAC->instUB); 2183 ISACLBStruct* instLB = &(instISAC->instLB); 2184 double bottleneckLB; 2185 double bottleneckUB; 2186 WebRtc_Word32 bottleneck = instISAC->bottleneck; 2187 WebRtc_Word16 codingMode = instISAC->codingMode; 2188 WebRtc_Word16 frameSizeMs = instLB->ISACencLB_obj.new_framelength / 2189 (FS / 1000); 2190 2191 if ((sampRate == kIsacWideband) && 2192 (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) { 2193 /* Changing from super-wideband to wideband. 2194 * we don't need to re-initialize the encoder of the lower-band. */ 2195 instISAC->bandwidthKHz = isac8kHz; 2196 if (codingMode == 1) { 2197 ControlLb(instLB, 2198 (bottleneck > 32000) ? 32000 : bottleneck, FRAMESIZE); 2199 } 2200 instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; 2201 instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; 2202 } else if ((sampRate == kIsacSuperWideband) && 2203 (instISAC->encoderSamplingRateKHz == kIsacWideband)) { 2204 if (codingMode == 1) { 2205 WebRtcIsac_RateAllocation(bottleneck, &bottleneckLB, &bottleneckUB, 2206 &(instISAC->bandwidthKHz)); 2207 } 2208 2209 instISAC->bandwidthKHz = isac16kHz; 2210 instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; 2211 instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; 2212 2213 EncoderInitLb(instLB, codingMode, sampRate); 2214 EncoderInitUb(instUB, instISAC->bandwidthKHz); 2215 2216 memset(instISAC->analysisFBState1, 0, 2217 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); 2218 memset(instISAC->analysisFBState2, 0, 2219 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); 2220 2221 if (codingMode == 1) { 2222 instISAC->bottleneck = bottleneck; 2223 ControlLb(instLB, bottleneckLB, 2224 (instISAC->bandwidthKHz == isac8kHz) ? frameSizeMs:FRAMESIZE); 2225 if (instISAC->bandwidthKHz > isac8kHz) { 2226 ControlUb(instUB, bottleneckUB); 2227 } 2228 } else { 2229 instLB->ISACencLB_obj.enforceFrameSize = 0; 2230 instLB->ISACencLB_obj.new_framelength = FRAMESAMPLES; 2231 } 2232 } 2233 instISAC->encoderSamplingRateKHz = sampRate; 2234 return 0; 2235 } 2236 } 2237 2238 2239 /****************************************************************************** 2240 * WebRtcIsac_SetDecSampRate() 2241 * This function sets the sampling rate of the decoder. Initialization of the 2242 * decoder WILL NOT overwrite the sampling rate of the encoder. The default 2243 * value is 16 kHz which is set when the instance is created. 2244 * 2245 * Input: 2246 * - ISAC_main_inst : iSAC instance 2247 * - sampRate : enumerator specifying the sampling rate. 2248 * 2249 * Return value : 0 if successful 2250 * -1 if failed. 2251 */ 2252 WebRtc_Word16 WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst, 2253 enum IsacSamplingRate sampRate) { 2254 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2255 2256 if ((sampRate != kIsacWideband) && 2257 (sampRate != kIsacSuperWideband)) { 2258 /* Sampling Frequency is not supported. */ 2259 instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; 2260 return -1; 2261 } else { 2262 if ((instISAC->decoderSamplingRateKHz == kIsacWideband) && 2263 (sampRate == kIsacSuperWideband)) { 2264 /* Switching from wideband to super-wideband at the decoder 2265 * we need to reset the filter-bank and initialize upper-band decoder. */ 2266 memset(instISAC->synthesisFBState1, 0, 2267 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); 2268 memset(instISAC->synthesisFBState2, 0, 2269 FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); 2270 2271 if (DecoderInitUb(&(instISAC->instUB)) < 0) { 2272 return -1; 2273 } 2274 } 2275 instISAC->decoderSamplingRateKHz = sampRate; 2276 return 0; 2277 } 2278 } 2279 2280 2281 /****************************************************************************** 2282 * WebRtcIsac_EncSampRate() 2283 * 2284 * Input: 2285 * - ISAC_main_inst : iSAC instance 2286 * 2287 * Return value : enumerator representing sampling frequency 2288 * associated with the encoder, the input audio 2289 * is expected to be sampled at this rate. 2290 * 2291 */ 2292 enum IsacSamplingRate WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst) { 2293 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2294 return instISAC->encoderSamplingRateKHz; 2295 } 2296 2297 2298 /****************************************************************************** 2299 * WebRtcIsac_DecSampRate() 2300 * Return the sampling rate of the decoded audio. 2301 * 2302 * Input: 2303 * - ISAC_main_inst : iSAC instance 2304 * 2305 * Return value : enumerator representing sampling frequency 2306 * associated with the decoder, i.e. the 2307 * sampling rate of the decoded audio. 2308 * 2309 */ 2310 enum IsacSamplingRate WebRtcIsac_DecSampRate(ISACStruct* ISAC_main_inst) { 2311 ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2312 return instISAC->decoderSamplingRateKHz; 2313 } 2314