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