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 #include "webrtc/modules/audio_coding/main/acm2/acm_isac.h" 11 12 #include <assert.h> 13 14 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h" 15 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" 16 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" 17 #include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h" 18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 19 #include "webrtc/system_wrappers/interface/trace.h" 20 21 #ifdef WEBRTC_CODEC_ISAC 22 #include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h" 23 #endif 24 25 #ifdef WEBRTC_CODEC_ISACFX 26 #include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h" 27 #endif 28 29 #if defined (WEBRTC_CODEC_ISAC) || defined (WEBRTC_CODEC_ISACFX) 30 #include "webrtc/modules/audio_coding/main/acm2/acm_isac_macros.h" 31 #endif 32 33 namespace webrtc { 34 35 namespace acm2 { 36 37 // we need this otherwise we cannot use forward declaration 38 // in the header file 39 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) 40 struct ACMISACInst { 41 ACM_ISAC_STRUCT* inst; 42 }; 43 #endif 44 45 #define ISAC_MIN_RATE 10000 46 #define ISAC_MAX_RATE 56000 47 48 // Tables for bandwidth estimates 49 #define NR_ISAC_BANDWIDTHS 24 50 static const int32_t kIsacRatesWb[NR_ISAC_BANDWIDTHS] = { 51 10000, 11100, 12300, 13700, 15200, 16900, 18800, 20900, 23300, 25900, 28700, 52 31900, 10100, 11200, 12400, 13800, 15300, 17000, 18900, 21000, 23400, 26000, 53 28800, 32000}; 54 55 static const int32_t kIsacRatesSwb[NR_ISAC_BANDWIDTHS] = { 56 10000, 11000, 12400, 13800, 15300, 17000, 18900, 21000, 23200, 25400, 27600, 57 29800, 32000, 34100, 36300, 38500, 40700, 42900, 45100, 47300, 49500, 51700, 58 53900, 56000 }; 59 60 #if (!defined(WEBRTC_CODEC_ISAC) && !defined(WEBRTC_CODEC_ISACFX)) 61 62 ACMISAC::ACMISAC(int16_t /* codec_id */) 63 : codec_inst_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 64 codec_inst_ptr_(NULL), 65 is_enc_initialized_(false), 66 isac_coding_mode_(CHANNEL_INDEPENDENT), 67 enforce_frame_size_(false), 68 isac_currentBN_(32000), 69 samples_in10MsAudio_(160), // Initiates to 16 kHz mode. 70 decoder_initialized_(false) { 71 } 72 73 ACMISAC::~ACMISAC() { 74 return; 75 } 76 77 ACMGenericCodec* ACMISAC::CreateInstance(void) { return NULL; } 78 79 int16_t ACMISAC::InternalEncode(uint8_t* /* bitstream */, 80 int16_t* /* bitstream_len_byte */) { 81 return -1; 82 } 83 84 int16_t ACMISAC::InternalInitEncoder(WebRtcACMCodecParams* /* codec_params */) { 85 return -1; 86 } 87 88 int16_t ACMISAC::InternalInitDecoder(WebRtcACMCodecParams* /* codec_params */) { 89 return -1; 90 } 91 92 int16_t ACMISAC::InternalCreateEncoder() { return -1; } 93 94 void ACMISAC::DestructEncoderSafe() { return; } 95 96 void ACMISAC::InternalDestructEncoderInst(void* /* ptr_inst */) { return; } 97 98 int16_t ACMISAC::Transcode(uint8_t* /* bitstream */, 99 int16_t* /* bitstream_len_byte */, 100 int16_t /* q_bwe */, 101 int32_t /* scale */, 102 bool /* is_red */) { 103 return -1; 104 } 105 106 int16_t ACMISAC::SetBitRateSafe(int32_t /* bit_rate */) { return -1; } 107 108 int32_t ACMISAC::GetEstimatedBandwidthSafe() { return -1; } 109 110 int32_t ACMISAC::SetEstimatedBandwidthSafe(int32_t /* estimated_bandwidth */) { 111 return -1; 112 } 113 114 int32_t ACMISAC::GetRedPayloadSafe(uint8_t* /* red_payload */, 115 int16_t* /* payload_bytes */) { 116 return -1; 117 } 118 119 int16_t ACMISAC::UpdateDecoderSampFreq(int16_t /* codec_id */) { return -1; } 120 121 int16_t ACMISAC::UpdateEncoderSampFreq(uint16_t /* encoder_samp_freq_hz */) { 122 return -1; 123 } 124 125 int16_t ACMISAC::EncoderSampFreq(uint16_t* /* samp_freq_hz */) { return -1; } 126 127 int32_t ACMISAC::ConfigISACBandwidthEstimator( 128 const uint8_t /* init_frame_size_msec */, 129 const uint16_t /* init_rate_bit_per_sec */, 130 const bool /* enforce_frame_size */) { 131 return -1; 132 } 133 134 int32_t ACMISAC::SetISACMaxPayloadSize( 135 const uint16_t /* max_payload_len_bytes */) { 136 return -1; 137 } 138 139 int32_t ACMISAC::SetISACMaxRate(const uint32_t /* max_rate_bit_per_sec */) { 140 return -1; 141 } 142 143 void ACMISAC::UpdateFrameLen() { return; } 144 145 void ACMISAC::CurrentRate(int32_t* /*rate_bit_per_sec */) { return; } 146 147 bool ACMISAC::DecoderParamsSafe(WebRtcACMCodecParams* /* dec_params */, 148 const uint8_t /* payload_type */) { 149 return false; 150 } 151 152 int16_t ACMISAC::REDPayloadISAC(const int32_t /* isac_rate */, 153 const int16_t /* isac_bw_estimate */, 154 uint8_t* /* payload */, 155 int16_t* /* payload_len_bytes */) { 156 return -1; 157 } 158 159 AudioDecoder* ACMISAC::Decoder(int /* codec_id */) { return NULL; } 160 161 #else //===================== Actual Implementation ======================= 162 163 #ifdef WEBRTC_CODEC_ISACFX 164 165 // How the scaling is computed. iSAC computes a gain based on the 166 // bottleneck. It follows the following expression for that 167 // 168 // G(BN_kbps) = pow(10, (a + b * BN_kbps + c * BN_kbps * BN_kbps) / 20.0) 169 // / 3.4641; 170 // 171 // Where for 30 ms framelength we have, 172 // 173 // a = -23; b = 0.48; c = 0; 174 // 175 // As the default encoder is operating at 32kbps we have the scale as 176 // 177 // S(BN_kbps) = G(BN_kbps) / G(32); 178 179 #define ISAC_NUM_SUPPORTED_RATES 9 180 181 static const uint16_t kIsacSuportedRates[ISAC_NUM_SUPPORTED_RATES] = { 182 32000, 30000, 26000, 23000, 21000, 19000, 17000, 15000, 12000}; 183 184 static const float kIsacScale[ISAC_NUM_SUPPORTED_RATES] = { 185 1.0f, 0.8954f, 0.7178f, 0.6081f, 0.5445f, 186 0.4875f, 0.4365f, 0.3908f, 0.3311f 187 }; 188 189 enum IsacSamplingRate { 190 kIsacWideband = 16, 191 kIsacSuperWideband = 32 192 }; 193 194 static float ACMISACFixTranscodingScale(uint16_t rate) { 195 // find the scale for transcoding, the scale is rounded 196 // downward 197 float scale = -1; 198 for (int16_t n = 0; n < ISAC_NUM_SUPPORTED_RATES; n++) { 199 if (rate >= kIsacSuportedRates[n]) { 200 scale = kIsacScale[n]; 201 break; 202 } 203 } 204 return scale; 205 } 206 207 static void ACMISACFixGetSendBitrate(ACM_ISAC_STRUCT* inst, 208 int32_t* bottleneck) { 209 *bottleneck = WebRtcIsacfix_GetUplinkBw(inst); 210 } 211 212 static int16_t ACMISACFixGetNewBitstream(ACM_ISAC_STRUCT* inst, 213 int16_t bwe_index, 214 int16_t /* jitter_index */, 215 int32_t rate, 216 int16_t* bitstream, 217 bool is_red) { 218 if (is_red) { 219 // RED not supported with iSACFIX 220 return -1; 221 } 222 float scale = ACMISACFixTranscodingScale((uint16_t)rate); 223 return WebRtcIsacfix_GetNewBitStream(inst, bwe_index, scale, bitstream); 224 } 225 226 static int16_t ACMISACFixGetSendBWE(ACM_ISAC_STRUCT* inst, 227 int16_t* rate_index, 228 int16_t* /* dummy */) { 229 int16_t local_rate_index; 230 int16_t status = WebRtcIsacfix_GetDownLinkBwIndex(inst, &local_rate_index); 231 if (status < 0) { 232 return -1; 233 } else { 234 *rate_index = local_rate_index; 235 return 0; 236 } 237 } 238 239 static int16_t ACMISACFixControlBWE(ACM_ISAC_STRUCT* inst, 240 int32_t rate_bps, 241 int16_t frame_size_ms, 242 int16_t enforce_frame_size) { 243 return WebRtcIsacfix_ControlBwe( 244 inst, (int16_t)rate_bps, frame_size_ms, enforce_frame_size); 245 } 246 247 static int16_t ACMISACFixControl(ACM_ISAC_STRUCT* inst, 248 int32_t rate_bps, 249 int16_t frame_size_ms) { 250 return WebRtcIsacfix_Control(inst, (int16_t)rate_bps, frame_size_ms); 251 } 252 253 // The following two function should have the same signature as their counter 254 // part in iSAC floating-point, i.e. WebRtcIsac_EncSampRate & 255 // WebRtcIsac_DecSampRate. 256 static uint16_t ACMISACFixGetEncSampRate(ACM_ISAC_STRUCT* /* inst */) { 257 return 16000; 258 } 259 260 static uint16_t ACMISACFixGetDecSampRate(ACM_ISAC_STRUCT* /* inst */) { 261 return 16000; 262 } 263 264 #endif 265 266 ACMISAC::ACMISAC(int16_t codec_id) 267 : AudioDecoder(ACMCodecDB::neteq_decoders_[codec_id]), 268 codec_inst_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 269 is_enc_initialized_(false), 270 isac_coding_mode_(CHANNEL_INDEPENDENT), 271 enforce_frame_size_(false), 272 isac_current_bn_(32000), 273 samples_in_10ms_audio_(160), // Initiates to 16 kHz mode. 274 decoder_initialized_(false) { 275 codec_id_ = codec_id; 276 277 // Create codec instance. 278 codec_inst_ptr_ = new ACMISACInst; 279 if (codec_inst_ptr_ == NULL) { 280 return; 281 } 282 codec_inst_ptr_->inst = NULL; 283 state_ = codec_inst_ptr_; 284 } 285 286 ACMISAC::~ACMISAC() { 287 if (codec_inst_ptr_ != NULL) { 288 if (codec_inst_ptr_->inst != NULL) { 289 ACM_ISAC_FREE(codec_inst_ptr_->inst); 290 codec_inst_ptr_->inst = NULL; 291 } 292 delete codec_inst_ptr_; 293 codec_inst_ptr_ = NULL; 294 } 295 return; 296 } 297 298 int16_t ACMISAC::InternalInitDecoder(WebRtcACMCodecParams* codec_params) { 299 // set decoder sampling frequency. 300 if (codec_params->codec_inst.plfreq == 32000 || 301 codec_params->codec_inst.plfreq == 48000) { 302 UpdateDecoderSampFreq(ACMCodecDB::kISACSWB); 303 } else { 304 UpdateDecoderSampFreq(ACMCodecDB::kISAC); 305 } 306 307 // in a one-way communication we may never register send-codec. 308 // However we like that the BWE to work properly so it has to 309 // be initialized. The BWE is initialized when iSAC encoder is initialized. 310 // Therefore, we need this. 311 if (!encoder_initialized_) { 312 // Since we don't require a valid rate or a valid packet size when 313 // initializing the decoder, we set valid values before initializing encoder 314 codec_params->codec_inst.rate = kIsacWbDefaultRate; 315 codec_params->codec_inst.pacsize = kIsacPacSize960; 316 if (InternalInitEncoder(codec_params) < 0) { 317 return -1; 318 } 319 encoder_initialized_ = true; 320 } 321 322 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 323 return ACM_ISAC_DECODERINIT(codec_inst_ptr_->inst); 324 } 325 326 ACMGenericCodec* ACMISAC::CreateInstance(void) { return NULL; } 327 328 int16_t ACMISAC::InternalEncode(uint8_t* bitstream, 329 int16_t* bitstream_len_byte) { 330 // ISAC takes 10ms audio every time we call encoder, therefore, 331 // it should be treated like codecs with 'basic coding block' 332 // non-zero, and the following 'while-loop' should not be necessary. 333 // However, due to a mistake in the codec the frame-size might change 334 // at the first 10ms pushed in to iSAC if the bit-rate is low, this is 335 // sort of a bug in iSAC. to address this we treat iSAC as the 336 // following. 337 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 338 if (codec_inst_ptr_ == NULL) { 339 return -1; 340 } 341 *bitstream_len_byte = 0; 342 while ((*bitstream_len_byte == 0) && (in_audio_ix_read_ < frame_len_smpl_)) { 343 if (in_audio_ix_read_ > in_audio_ix_write_) { 344 // something is wrong. 345 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, 346 "The actual frame-size of iSAC appears to be larger that " 347 "expected. All audio pushed in but no bit-stream is " 348 "generated."); 349 return -1; 350 } 351 *bitstream_len_byte = ACM_ISAC_ENCODE( 352 codec_inst_ptr_->inst, &in_audio_[in_audio_ix_read_], 353 reinterpret_cast<int16_t*>(bitstream)); 354 // increment the read index this tell the caller that how far 355 // we have gone forward in reading the audio buffer 356 in_audio_ix_read_ += samples_in_10ms_audio_; 357 } 358 if (*bitstream_len_byte == 0) { 359 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, unique_id_, 360 "ISAC Has encoded the whole frame but no bit-stream is " 361 "generated."); 362 } 363 364 // a packet is generated iSAC, is set in adaptive mode may change 365 // the frame length and we like to update the bottleneck value as 366 // well, although updating bottleneck is not crucial 367 if ((*bitstream_len_byte > 0) && (isac_coding_mode_ == ADAPTIVE)) { 368 ACM_ISAC_GETSENDBITRATE(codec_inst_ptr_->inst, &isac_current_bn_); 369 } 370 UpdateFrameLen(); 371 return *bitstream_len_byte; 372 } 373 374 int16_t ACMISAC::InternalInitEncoder(WebRtcACMCodecParams* codec_params) { 375 // if rate is set to -1 then iSAC has to be in adaptive mode 376 if (codec_params->codec_inst.rate == -1) { 377 isac_coding_mode_ = ADAPTIVE; 378 } else if ((codec_params->codec_inst.rate >= ISAC_MIN_RATE) && 379 (codec_params->codec_inst.rate <= ISAC_MAX_RATE)) { 380 // sanity check that rate is in acceptable range 381 isac_coding_mode_ = CHANNEL_INDEPENDENT; 382 isac_current_bn_ = codec_params->codec_inst.rate; 383 } else { 384 return -1; 385 } 386 387 // we need to set the encoder sampling frequency. 388 if (UpdateEncoderSampFreq((uint16_t)codec_params->codec_inst.plfreq) < 0) { 389 return -1; 390 } 391 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 392 if (ACM_ISAC_ENCODERINIT(codec_inst_ptr_->inst, isac_coding_mode_) < 0) { 393 return -1; 394 } 395 396 // apply the frame-size and rate if operating in 397 // channel-independent mode 398 if (isac_coding_mode_ == CHANNEL_INDEPENDENT) { 399 if (ACM_ISAC_CONTROL(codec_inst_ptr_->inst, 400 codec_params->codec_inst.rate, 401 codec_params->codec_inst.pacsize / 402 (codec_params->codec_inst.plfreq / 1000)) < 0) { 403 return -1; 404 } 405 } else { 406 // We need this for adaptive case and has to be called 407 // after initialization 408 ACM_ISAC_GETSENDBITRATE(codec_inst_ptr_->inst, &isac_current_bn_); 409 } 410 frame_len_smpl_ = ACM_ISAC_GETNEWFRAMELEN(codec_inst_ptr_->inst); 411 return 0; 412 } 413 414 int16_t ACMISAC::InternalCreateEncoder() { 415 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 416 if (codec_inst_ptr_ == NULL) { 417 return -1; 418 } 419 decoder_initialized_ = false; 420 int16_t status = ACM_ISAC_CREATE(&(codec_inst_ptr_->inst)); 421 422 if (status < 0) 423 codec_inst_ptr_->inst = NULL; 424 return status; 425 } 426 427 int16_t ACMISAC::Transcode(uint8_t* bitstream, 428 int16_t* bitstream_len_byte, 429 int16_t q_bwe, 430 int32_t rate, 431 bool is_red) { 432 int16_t jitter_info = 0; 433 // transcode from a higher rate to lower rate sanity check 434 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 435 if (codec_inst_ptr_ == NULL) { 436 return -1; 437 } 438 439 *bitstream_len_byte = ACM_ISAC_GETNEWBITSTREAM( 440 codec_inst_ptr_->inst, q_bwe, jitter_info, rate, 441 reinterpret_cast<int16_t*>(bitstream), (is_red) ? 1 : 0); 442 443 if (*bitstream_len_byte < 0) { 444 // error happened 445 *bitstream_len_byte = 0; 446 return -1; 447 } else { 448 return *bitstream_len_byte; 449 } 450 } 451 452 void ACMISAC::UpdateFrameLen() { 453 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 454 frame_len_smpl_ = ACM_ISAC_GETNEWFRAMELEN(codec_inst_ptr_->inst); 455 encoder_params_.codec_inst.pacsize = frame_len_smpl_; 456 } 457 458 void ACMISAC::DestructEncoderSafe() { 459 // codec with shared instance cannot delete. 460 encoder_initialized_ = false; 461 return; 462 } 463 464 void ACMISAC::InternalDestructEncoderInst(void* ptr_inst) { 465 if (ptr_inst != NULL) { 466 ACM_ISAC_FREE(static_cast<ACM_ISAC_STRUCT *>(ptr_inst)); 467 } 468 return; 469 } 470 471 int16_t ACMISAC::SetBitRateSafe(int32_t bit_rate) { 472 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 473 if (codec_inst_ptr_ == NULL) { 474 return -1; 475 } 476 uint16_t encoder_samp_freq; 477 EncoderSampFreq(&encoder_samp_freq); 478 bool reinit = false; 479 // change the BN of iSAC 480 if (bit_rate == -1) { 481 // ADAPTIVE MODE 482 // Check if it was already in adaptive mode 483 if (isac_coding_mode_ != ADAPTIVE) { 484 // was not in adaptive, then set the mode to adaptive 485 // and flag for re-initialization 486 isac_coding_mode_ = ADAPTIVE; 487 reinit = true; 488 } 489 } else if ((bit_rate >= ISAC_MIN_RATE) && (bit_rate <= ISAC_MAX_RATE)) { 490 // Sanity check if the rate valid 491 // check if it was in channel-independent mode before 492 if (isac_coding_mode_ != CHANNEL_INDEPENDENT) { 493 // was not in channel independent, set the mode to 494 // channel-independent and flag for re-initialization 495 isac_coding_mode_ = CHANNEL_INDEPENDENT; 496 reinit = true; 497 } 498 // store the bottleneck 499 isac_current_bn_ = (uint16_t)bit_rate; 500 } else { 501 // invlaid rate 502 return -1; 503 } 504 505 int16_t status = 0; 506 if (reinit) { 507 // initialize and check if it is successful 508 if (ACM_ISAC_ENCODERINIT(codec_inst_ptr_->inst, isac_coding_mode_) < 0) { 509 // failed initialization 510 return -1; 511 } 512 } 513 if (isac_coding_mode_ == CHANNEL_INDEPENDENT) { 514 status = ACM_ISAC_CONTROL( 515 codec_inst_ptr_->inst, isac_current_bn_, 516 (encoder_samp_freq == 32000 || encoder_samp_freq == 48000) ? 30 : 517 (frame_len_smpl_ / 16)); 518 if (status < 0) { 519 status = -1; 520 } 521 } 522 523 // Update encoder parameters 524 encoder_params_.codec_inst.rate = bit_rate; 525 526 UpdateFrameLen(); 527 return status; 528 } 529 530 int32_t ACMISAC::GetEstimatedBandwidthSafe() { 531 int16_t bandwidth_index = 0; 532 int16_t delay_index = 0; 533 int samp_rate; 534 535 // Get bandwidth information 536 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 537 ACM_ISAC_GETSENDBWE(codec_inst_ptr_->inst, &bandwidth_index, &delay_index); 538 539 // Validy check of index 540 if ((bandwidth_index < 0) || (bandwidth_index >= NR_ISAC_BANDWIDTHS)) { 541 return -1; 542 } 543 544 // Check sample frequency 545 samp_rate = ACM_ISAC_GETDECSAMPRATE(codec_inst_ptr_->inst); 546 if (samp_rate == 16000) { 547 return kIsacRatesWb[bandwidth_index]; 548 } else { 549 return kIsacRatesSwb[bandwidth_index]; 550 } 551 } 552 553 int32_t ACMISAC::SetEstimatedBandwidthSafe(int32_t estimated_bandwidth) { 554 int samp_rate; 555 int16_t bandwidth_index; 556 557 // Check sample frequency and choose appropriate table 558 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 559 samp_rate = ACM_ISAC_GETENCSAMPRATE(codec_inst_ptr_->inst); 560 561 if (samp_rate == 16000) { 562 // Search through the WB rate table to find the index 563 bandwidth_index = NR_ISAC_BANDWIDTHS / 2 - 1; 564 for (int i = 0; i < (NR_ISAC_BANDWIDTHS / 2); i++) { 565 if (estimated_bandwidth == kIsacRatesWb[i]) { 566 bandwidth_index = i; 567 break; 568 } else if (estimated_bandwidth 569 == kIsacRatesWb[i + NR_ISAC_BANDWIDTHS / 2]) { 570 bandwidth_index = i + NR_ISAC_BANDWIDTHS / 2; 571 break; 572 } else if (estimated_bandwidth < kIsacRatesWb[i]) { 573 bandwidth_index = i; 574 break; 575 } 576 } 577 } else { 578 // Search through the SWB rate table to find the index 579 bandwidth_index = NR_ISAC_BANDWIDTHS - 1; 580 for (int i = 0; i < NR_ISAC_BANDWIDTHS; i++) { 581 if (estimated_bandwidth <= kIsacRatesSwb[i]) { 582 bandwidth_index = i; 583 break; 584 } 585 } 586 } 587 588 // Set iSAC Bandwidth Estimate 589 ACM_ISAC_SETBWE(codec_inst_ptr_->inst, bandwidth_index); 590 591 return 0; 592 } 593 594 int32_t ACMISAC::GetRedPayloadSafe( 595 #if (!defined(WEBRTC_CODEC_ISAC)) 596 uint8_t* /* red_payload */, 597 int16_t* /* payload_bytes */) { 598 return -1; 599 #else 600 uint8_t* red_payload, int16_t* payload_bytes) { 601 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 602 int16_t bytes = 603 WebRtcIsac_GetRedPayload( 604 codec_inst_ptr_->inst, reinterpret_cast<int16_t*>(red_payload)); 605 if (bytes < 0) { 606 return -1; 607 } 608 *payload_bytes = bytes; 609 return 0; 610 #endif 611 } 612 613 int16_t ACMISAC::UpdateDecoderSampFreq( 614 #ifdef WEBRTC_CODEC_ISAC 615 int16_t codec_id) { 616 // The decoder supports only wideband and super-wideband. 617 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 618 if (ACMCodecDB::kISAC == codec_id) { 619 return WebRtcIsac_SetDecSampRate(codec_inst_ptr_->inst, 16000); 620 } else if (ACMCodecDB::kISACSWB == codec_id || 621 ACMCodecDB::kISACFB == codec_id) { 622 return WebRtcIsac_SetDecSampRate(codec_inst_ptr_->inst, 32000); 623 } else { 624 return -1; 625 } 626 #else 627 int16_t /* codec_id */) { 628 return 0; 629 #endif 630 } 631 632 int16_t ACMISAC::UpdateEncoderSampFreq( 633 #ifdef WEBRTC_CODEC_ISAC 634 uint16_t encoder_samp_freq_hz) { 635 uint16_t current_samp_rate_hz; 636 EncoderSampFreq(¤t_samp_rate_hz); 637 638 if (current_samp_rate_hz != encoder_samp_freq_hz) { 639 if ((encoder_samp_freq_hz != 16000) && (encoder_samp_freq_hz != 32000) && 640 (encoder_samp_freq_hz != 48000)) { 641 return -1; 642 } else { 643 in_audio_ix_read_ = 0; 644 in_audio_ix_write_ = 0; 645 in_timestamp_ix_write_ = 0; 646 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 647 if (WebRtcIsac_SetEncSampRate(codec_inst_ptr_->inst, 648 encoder_samp_freq_hz) < 0) { 649 return -1; 650 } 651 samples_in_10ms_audio_ = encoder_samp_freq_hz / 100; 652 frame_len_smpl_ = ACM_ISAC_GETNEWFRAMELEN(codec_inst_ptr_->inst); 653 encoder_params_.codec_inst.pacsize = frame_len_smpl_; 654 encoder_params_.codec_inst.plfreq = encoder_samp_freq_hz; 655 return 0; 656 } 657 } 658 #else 659 uint16_t /* codec_id */) { 660 #endif 661 return 0; 662 } 663 664 int16_t ACMISAC::EncoderSampFreq(uint16_t* samp_freq_hz) { 665 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 666 *samp_freq_hz = ACM_ISAC_GETENCSAMPRATE(codec_inst_ptr_->inst); 667 return 0; 668 } 669 670 int32_t ACMISAC::ConfigISACBandwidthEstimator( 671 const uint8_t init_frame_size_msec, 672 const uint16_t init_rate_bit_per_sec, 673 const bool enforce_frame_size) { 674 int16_t status; 675 { 676 uint16_t samp_freq_hz; 677 EncoderSampFreq(&samp_freq_hz); 678 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 679 // TODO(turajs): at 32kHz we hardcode calling with 30ms and enforce 680 // the frame-size otherwise we might get error. Revise if 681 // control-bwe is changed. 682 if (samp_freq_hz == 32000 || samp_freq_hz == 48000) { 683 status = ACM_ISAC_CONTROL_BWE(codec_inst_ptr_->inst, 684 init_rate_bit_per_sec, 30, 1); 685 } else { 686 status = ACM_ISAC_CONTROL_BWE(codec_inst_ptr_->inst, 687 init_rate_bit_per_sec, 688 init_frame_size_msec, 689 enforce_frame_size ? 1 : 0); 690 } 691 } 692 if (status < 0) { 693 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, 694 "Couldn't config iSAC BWE."); 695 return -1; 696 } 697 UpdateFrameLen(); 698 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 699 ACM_ISAC_GETSENDBITRATE(codec_inst_ptr_->inst, &isac_current_bn_); 700 return 0; 701 } 702 703 int32_t ACMISAC::SetISACMaxPayloadSize(const uint16_t max_payload_len_bytes) { 704 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 705 return ACM_ISAC_SETMAXPAYLOADSIZE(codec_inst_ptr_->inst, 706 max_payload_len_bytes); 707 } 708 709 int32_t ACMISAC::SetISACMaxRate(const uint32_t max_rate_bit_per_sec) { 710 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 711 return ACM_ISAC_SETMAXRATE(codec_inst_ptr_->inst, max_rate_bit_per_sec); 712 } 713 714 void ACMISAC::CurrentRate(int32_t* rate_bit_per_sec) { 715 if (isac_coding_mode_ == ADAPTIVE) { 716 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 717 ACM_ISAC_GETSENDBITRATE(codec_inst_ptr_->inst, rate_bit_per_sec); 718 } 719 } 720 721 int16_t ACMISAC::REDPayloadISAC(const int32_t isac_rate, 722 const int16_t isac_bw_estimate, 723 uint8_t* payload, 724 int16_t* payload_len_bytes) { 725 int16_t status; 726 ReadLockScoped rl(codec_wrapper_lock_); 727 status = 728 Transcode(payload, payload_len_bytes, isac_bw_estimate, isac_rate, true); 729 return status; 730 } 731 732 int ACMISAC::Decode(const uint8_t* encoded, 733 size_t encoded_len, 734 int16_t* decoded, 735 SpeechType* speech_type) { 736 int16_t temp_type; 737 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 738 int ret = 739 ACM_ISAC_DECODE_B(static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst), 740 reinterpret_cast<const uint16_t*>(encoded), 741 static_cast<int16_t>(encoded_len), 742 decoded, 743 &temp_type); 744 *speech_type = ConvertSpeechType(temp_type); 745 return ret; 746 } 747 748 int ACMISAC::DecodePlc(int num_frames, int16_t* decoded) { 749 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 750 return ACM_ISAC_DECODEPLC( 751 static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst), 752 decoded, 753 static_cast<int16_t>(num_frames)); 754 } 755 756 int ACMISAC::IncomingPacket(const uint8_t* payload, 757 size_t payload_len, 758 uint16_t rtp_sequence_number, 759 uint32_t rtp_timestamp, 760 uint32_t arrival_timestamp) { 761 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 762 return ACM_ISAC_DECODE_BWE( 763 static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst), 764 reinterpret_cast<const uint16_t*>(payload), 765 static_cast<uint32_t>(payload_len), 766 rtp_sequence_number, 767 rtp_timestamp, 768 arrival_timestamp); 769 } 770 771 int ACMISAC::DecodeRedundant(const uint8_t* encoded, 772 size_t encoded_len, 773 int16_t* decoded, 774 SpeechType* speech_type) { 775 int16_t temp_type = 1; // Default is speech. 776 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 777 int16_t ret = 778 ACM_ISAC_DECODERCU(static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst), 779 reinterpret_cast<const uint16_t*>(encoded), 780 static_cast<int16_t>(encoded_len), 781 decoded, 782 &temp_type); 783 *speech_type = ConvertSpeechType(temp_type); 784 return ret; 785 } 786 787 int ACMISAC::ErrorCode() { 788 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 789 return ACM_ISAC_GETERRORCODE( 790 static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst)); 791 } 792 793 AudioDecoder* ACMISAC::Decoder(int codec_id) { 794 // Create iSAC instance if it does not exist. 795 if (!encoder_exist_) { 796 CriticalSectionScoped lock(codec_inst_crit_sect_.get()); 797 assert(codec_inst_ptr_->inst == NULL); 798 encoder_initialized_ = false; 799 decoder_initialized_ = false; 800 if (ACM_ISAC_CREATE(&(codec_inst_ptr_->inst)) < 0) { 801 codec_inst_ptr_->inst = NULL; 802 return NULL; 803 } 804 encoder_exist_ = true; 805 } 806 807 WebRtcACMCodecParams codec_params; 808 if (!encoder_initialized_ || !decoder_initialized_) { 809 ACMCodecDB::Codec(codec_id, &codec_params.codec_inst); 810 // The following three values are not used but we set them to valid values. 811 codec_params.enable_dtx = false; 812 codec_params.enable_vad = false; 813 codec_params.vad_mode = VADNormal; 814 } 815 816 if (!encoder_initialized_) { 817 // Initialize encoder to make sure bandwidth estimator works. 818 if (InternalInitEncoder(&codec_params) < 0) 819 return NULL; 820 encoder_initialized_ = true; 821 } 822 823 if (!decoder_initialized_) { 824 if (InternalInitDecoder(&codec_params) < 0) 825 return NULL; 826 decoder_initialized_ = true; 827 } 828 829 return this; 830 } 831 832 #endif 833 834 } // namespace acm2 835 836 } // namespace webrtc 837