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 
     11 #include "webrtc/modules/audio_coding/main/acm2/acm_amrwb.h"
     12 
     13 #ifdef WEBRTC_CODEC_AMRWB
     14 // NOTE! GSM AMR-wb is not included in the open-source package. The
     15 // following interface file is needed:
     16 #include "webrtc/modules/audio_coding/main/codecs/amrwb/interface/amrwb_interface.h"
     17 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
     18 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
     19 #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
     20 #include "webrtc/system_wrappers/interface/trace.h"
     21 
     22 // The API in the header file should match the one below.
     23 //
     24 // int16_t WebRtcAmrWb_CreateEnc(AMRWB_encinst_t_** enc_inst);
     25 // int16_t WebRtcAmrWb_CreateDec(AMRWB_decinst_t_** dec_inst);
     26 // int16_t WebRtcAmrWb_FreeEnc(AMRWB_encinst_t_* enc_inst);
     27 // int16_t WebRtcAmrWb_FreeDec(AMRWB_decinst_t_* dec_inst);
     28 // int16_t WebRtcAmrWb_Encode(AMRWB_encinst_t_* enc_inst, int16_t* input,
     29 //                            int16_t len, int16_t* output, int16_t mode);
     30 // int16_t WebRtcAmrWb_EncoderInit(AMRWB_encinst_t_* enc_inst,
     31 //                                 int16_t dtx_mode);
     32 // int16_t WebRtcAmrWb_EncodeBitmode(AMRWB_encinst_t_* enc_inst,
     33 //                                    int format);
     34 // int16_t WebRtcAmrWb_Decode(AMRWB_decinst_t_* dec_inst);
     35 // int16_t WebRtcAmrWb_DecodePlc(AMRWB_decinst_t_* dec_inst);
     36 // int16_t WebRtcAmrWb_DecoderInit(AMRWB_decinst_t_* dec_inst);
     37 // int16_t WebRtcAmrWb_DecodeBitmode(AMRWB_decinst_t_* dec_inst,
     38 //                                   int format);
     39 #endif
     40 
     41 namespace webrtc {
     42 
     43 namespace acm2 {
     44 
     45 #ifndef WEBRTC_CODEC_AMRWB
     46 ACMAMRwb::ACMAMRwb(int16_t /* codec_id */)
     47     : encoder_inst_ptr_(NULL),
     48       encoding_mode_(-1),  // invalid value
     49       encoding_rate_(0),   // invalid value
     50       encoder_packing_format_(AMRBandwidthEfficient) {}
     51 
     52 ACMAMRwb::~ACMAMRwb() {}
     53 
     54 int16_t ACMAMRwb::InternalEncode(uint8_t* /* bitstream */,
     55                                  int16_t* /* bitstream_len_byte */) {
     56   return -1;
     57 }
     58 
     59 int16_t ACMAMRwb::EnableDTX() { return -1; }
     60 
     61 int16_t ACMAMRwb::DisableDTX() { return -1; }
     62 
     63 int16_t ACMAMRwb::InternalInitEncoder(
     64     WebRtcACMCodecParams* /* codec_params */) {
     65   return -1;
     66 }
     67 
     68 ACMGenericCodec* ACMAMRwb::CreateInstance(void) { return NULL; }
     69 
     70 int16_t ACMAMRwb::InternalCreateEncoder() { return -1; }
     71 
     72 void ACMAMRwb::DestructEncoderSafe() { return; }
     73 
     74 int16_t ACMAMRwb::SetBitRateSafe(const int32_t /* rate */) { return -1; }
     75 
     76 void ACMAMRwb::InternalDestructEncoderInst(void* /* ptr_inst */) { return; }
     77 
     78 int16_t ACMAMRwb::SetAMRwbEncoderPackingFormat(
     79     ACMAMRPackingFormat /* packing_format */) {
     80   return -1;
     81 }
     82 
     83 ACMAMRPackingFormat ACMAMRwb::AMRwbEncoderPackingFormat() const {
     84   return AMRUndefined;
     85 }
     86 
     87 int16_t ACMAMRwb::SetAMRwbDecoderPackingFormat(
     88     ACMAMRPackingFormat /* packing_format */) {
     89   return -1;
     90 }
     91 
     92 ACMAMRPackingFormat ACMAMRwb::AMRwbDecoderPackingFormat() const {
     93   return AMRUndefined;
     94 }
     95 
     96 #else     //===================== Actual Implementation =======================
     97 
     98 #define AMRWB_MODE_7k 0
     99 #define AMRWB_MODE_9k 1
    100 #define AMRWB_MODE_12k 2
    101 #define AMRWB_MODE_14k 3
    102 #define AMRWB_MODE_16k 4
    103 #define AMRWB_MODE_18k 5
    104 #define AMRWB_MODE_20k 6
    105 #define AMRWB_MODE_23k 7
    106 #define AMRWB_MODE_24k 8
    107 
    108 ACMAMRwb::ACMAMRwb(int16_t codec_id)
    109     : encoder_inst_ptr_(NULL),
    110       encoding_mode_(-1),  // invalid value
    111       encoding_rate_(0) {  // invalid value
    112   codec_id_ = codec_id;
    113   has_internal_dtx_ = true;
    114   encoder_packing_format_ = AMRBandwidthEfficient;
    115   return;
    116 }
    117 
    118 ACMAMRwb::~ACMAMRwb() {
    119   if (encoder_inst_ptr_ != NULL) {
    120     WebRtcAmrWb_FreeEnc(encoder_inst_ptr_);
    121     encoder_inst_ptr_ = NULL;
    122   }
    123   return;
    124 }
    125 
    126 int16_t ACMAMRwb::InternalEncode(uint8_t* bitstream,
    127                                  int16_t* bitstream_len_byte) {
    128   int16_t vad_decision = 1;
    129   // sanity check, if the rate is set correctly. we might skip this
    130   // sanity check. if rate is not set correctly, initialization flag
    131   // should be false and should not be here.
    132   if ((encoding_mode_ < AMRWB_MODE_7k) || (encoding_mode_ > AMRWB_MODE_24k)) {
    133     *bitstream_len_byte = 0;
    134     return -1;
    135   }
    136   *bitstream_len_byte = WebRtcAmrWb_Encode(
    137       encoder_inst_ptr_, &in_audio_[in_audio_ix_read_], frame_len_smpl_,
    138       reinterpret_cast<int16_t*>(bitstream), encoding_mode_);
    139 
    140   // Update VAD, if internal DTX is used
    141   if (has_internal_dtx_ && dtx_enabled_) {
    142     if (*bitstream_len_byte <= (7 * frame_len_smpl_ / 160)) {
    143       vad_decision = 0;
    144     }
    145     for (int16_t n = 0; n < MAX_FRAME_SIZE_10MSEC; n++) {
    146       vad_label_[n] = vad_decision;
    147     }
    148   }
    149   // increment the read index this tell the caller that how far
    150   // we have gone forward in reading the audio buffer
    151   in_audio_ix_read_ += frame_len_smpl_;
    152   return *bitstream_len_byte;
    153 }
    154 
    155 int16_t ACMAMRwb::EnableDTX() {
    156   if (dtx_enabled_) {
    157     return 0;
    158   } else if (encoder_exist_) {  // check if encoder exist
    159     // enable DTX
    160     if (WebRtcAmrWb_EncoderInit(encoder_inst_ptr_, 1) < 0) {
    161       return -1;
    162     }
    163     dtx_enabled_ = true;
    164     return 0;
    165   } else {
    166     return -1;
    167   }
    168 }
    169 
    170 int16_t ACMAMRwb::DisableDTX() {
    171   if (!dtx_enabled_) {
    172     return 0;
    173   } else if (encoder_exist_) {  // check if encoder exist
    174     // disable DTX
    175     if (WebRtcAmrWb_EncoderInit(encoder_inst_ptr_, 0) < 0) {
    176       return -1;
    177     }
    178     dtx_enabled_ = false;
    179     return 0;
    180   } else {
    181     // encoder doesn't exists, therefore disabling is harmless
    182     return 0;
    183   }
    184 }
    185 
    186 int16_t ACMAMRwb::InternalInitEncoder(WebRtcACMCodecParams* codec_params) {
    187   // sanity check
    188   if (encoder_inst_ptr_ == NULL) {
    189     return -1;
    190   }
    191 
    192   int16_t status = SetBitRateSafe((codec_params->codec_inst).rate);
    193   status += (WebRtcAmrWb_EncoderInit(encoder_inst_ptr_,
    194                                      ((codec_params->enable_dtx) ? 1 : 0)) < 0)
    195                 ? -1
    196                 : 0;
    197   status += (WebRtcAmrWb_EncodeBitmode(encoder_inst_ptr_,
    198                                        encoder_packing_format_) < 0)
    199                 ? -1
    200                 : 0;
    201   return (status < 0) ? -1 : 0;
    202 }
    203 
    204 ACMGenericCodec* ACMAMRwb::CreateInstance(void) { return NULL; }
    205 
    206 int16_t ACMAMRwb::InternalCreateEncoder() {
    207   return WebRtcAmrWb_CreateEnc(&encoder_inst_ptr_);
    208 }
    209 
    210 void ACMAMRwb::DestructEncoderSafe() {
    211   if (encoder_inst_ptr_ != NULL) {
    212     WebRtcAmrWb_FreeEnc(encoder_inst_ptr_);
    213     encoder_inst_ptr_ = NULL;
    214   }
    215   // there is no encoder set the following
    216   encoder_exist_ = false;
    217   encoder_initialized_ = false;
    218   encoding_mode_ = -1;  // invalid value
    219   encoding_rate_ = 0;
    220 }
    221 
    222 int16_t ACMAMRwb::SetBitRateSafe(const int32_t rate) {
    223   switch (rate) {
    224     case 7000: {
    225       encoding_mode_ = AMRWB_MODE_7k;
    226       encoding_rate_ = 7000;
    227       break;
    228     }
    229     case 9000: {
    230       encoding_mode_ = AMRWB_MODE_9k;
    231       encoding_rate_ = 9000;
    232       break;
    233     }
    234     case 12000: {
    235       encoding_mode_ = AMRWB_MODE_12k;
    236       encoding_rate_ = 12000;
    237       break;
    238     }
    239     case 14000: {
    240       encoding_mode_ = AMRWB_MODE_14k;
    241       encoding_rate_ = 14000;
    242       break;
    243     }
    244     case 16000: {
    245       encoding_mode_ = AMRWB_MODE_16k;
    246       encoding_rate_ = 16000;
    247       break;
    248     }
    249     case 18000: {
    250       encoding_mode_ = AMRWB_MODE_18k;
    251       encoding_rate_ = 18000;
    252       break;
    253     }
    254     case 20000: {
    255       encoding_mode_ = AMRWB_MODE_20k;
    256       encoding_rate_ = 20000;
    257       break;
    258     }
    259     case 23000: {
    260       encoding_mode_ = AMRWB_MODE_23k;
    261       encoding_rate_ = 23000;
    262       break;
    263     }
    264     case 24000: {
    265       encoding_mode_ = AMRWB_MODE_24k;
    266       encoding_rate_ = 24000;
    267       break;
    268     }
    269     default: {
    270       return -1;
    271     }
    272   }
    273   return 0;
    274 }
    275 
    276 void ACMAMRwb::InternalDestructEncoderInst(void* ptr_inst) {
    277   if (ptr_inst != NULL) {
    278     WebRtcAmrWb_FreeEnc(static_cast<AMRWB_encinst_t_*>(ptr_inst));
    279   }
    280   return;
    281 }
    282 
    283 int16_t ACMAMRwb::SetAMRwbEncoderPackingFormat(
    284     ACMAMRPackingFormat packing_format) {
    285   if ((packing_format != AMRBandwidthEfficient) &&
    286       (packing_format != AMROctetAlligned) &&
    287       (packing_format != AMRFileStorage)) {
    288     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
    289                  "Invalid AMRwb encoder packing-format.");
    290     return -1;
    291   } else {
    292     if (WebRtcAmrWb_EncodeBitmode(encoder_inst_ptr_, packing_format) < 0) {
    293       return -1;
    294     } else {
    295       encoder_packing_format_ = packing_format;
    296       return 0;
    297     }
    298   }
    299 }
    300 
    301 ACMAMRPackingFormat ACMAMRwb::AMRwbEncoderPackingFormat() const {
    302   return encoder_packing_format_;
    303 }
    304 
    305 int16_t ACMAMRwb::SetAMRwbDecoderPackingFormat(
    306     ACMAMRPackingFormat packing_format) {
    307   // Not implemented.
    308   return -1;
    309 }
    310 
    311 ACMAMRPackingFormat ACMAMRwb::AMRwbDecoderPackingFormat() const {
    312   // Not implemented.
    313   return AMRUndefined;
    314 }
    315 
    316 #endif
    317 
    318 }  // namespace acm2
    319 
    320 }  // namespace webrtc
    321