Home | History | Annotate | Download | only in acm2
      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(&current_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