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_g7291.h"
     12 
     13 #ifdef WEBRTC_CODEC_G729_1
     14 // NOTE! G.729.1 is not included in the open-source package. Modify this file
     15 // or your codec API to match the function calls and names of used G.729.1 API
     16 // file.
     17 #include "webrtc/modules/audio_coding/main/codecs/g7291/interface/g7291_interface.h"
     18 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
     19 #include "webrtc/system_wrappers/interface/trace.h"
     20 #endif
     21 
     22 namespace webrtc {
     23 
     24 namespace acm2 {
     25 
     26 #ifndef WEBRTC_CODEC_G729_1
     27 
     28 ACMG729_1::ACMG729_1(int16_t /* codec_id */)
     29     : encoder_inst_ptr_(NULL),
     30       my_rate_(32000),
     31       flag_8khz_(0),
     32       flag_g729_mode_(0) {
     33   return;
     34 }
     35 
     36 ACMG729_1::~ACMG729_1() { return; }
     37 
     38 int16_t ACMG729_1::InternalEncode(uint8_t* /* bitstream */,
     39                                   int16_t* /* bitstream_len_byte */) {
     40   return -1;
     41 }
     42 
     43 int16_t ACMG729_1::InternalInitEncoder(
     44     WebRtcACMCodecParams* /* codec_params */) {
     45   return -1;
     46 }
     47 
     48 ACMGenericCodec* ACMG729_1::CreateInstance(void) { return NULL; }
     49 
     50 int16_t ACMG729_1::InternalCreateEncoder() { return -1; }
     51 
     52 void ACMG729_1::DestructEncoderSafe() { return; }
     53 
     54 int16_t ACMG729_1::SetBitRateSafe(const int32_t /*rate*/) { return -1; }
     55 
     56 #else  //===================== Actual Implementation =======================
     57 
     58 struct G729_1_inst_t_;
     59 
     60 ACMG729_1::ACMG729_1(int16_t codec_id)
     61     : encoder_inst_ptr_(NULL),
     62       my_rate_(32000),  // Default rate.
     63       flag_8khz_(0),
     64       flag_g729_mode_(0) {
     65   // TODO(tlegrand): We should add codec_id as a input variable to the
     66   // constructor of ACMGenericCodec.
     67   codec_id_ = codec_id;
     68   return;
     69 }
     70 
     71 ACMG729_1::~ACMG729_1() {
     72   if (encoder_inst_ptr_ != NULL) {
     73     WebRtcG7291_Free(encoder_inst_ptr_);
     74     encoder_inst_ptr_ = NULL;
     75   }
     76   return;
     77 }
     78 
     79 int16_t ACMG729_1::InternalEncode(uint8_t* bitstream,
     80                                   int16_t* bitstream_len_byte) {
     81   // Initialize before entering the loop
     82   int16_t num_encoded_samples = 0;
     83   *bitstream_len_byte = 0;
     84 
     85   int16_t byte_length_frame = 0;
     86 
     87   // Derive number of 20ms frames per encoded packet.
     88   // [1,2,3] <=> [20,40,60]ms <=> [320,640,960] samples
     89   int16_t num_20ms_frames = (frame_len_smpl_ / 320);
     90   // Byte length for the frame. +1 is for rate information.
     91   byte_length_frame =
     92       my_rate_ / (8 * 50) * num_20ms_frames + (1 - flag_g729_mode_);
     93 
     94   // The following might be revised if we have G729.1 Annex C (support for DTX);
     95   do {
     96     *bitstream_len_byte = WebRtcG7291_Encode(
     97         encoder_inst_ptr_, &in_audio_[in_audio_ix_read_],
     98         reinterpret_cast<int16_t*>(bitstream), my_rate_, num_20ms_frames);
     99 
    100     // increment the read index this tell the caller that how far
    101     // we have gone forward in reading the audio buffer
    102     in_audio_ix_read_ += 160;
    103 
    104     // sanity check
    105     if (*bitstream_len_byte < 0) {
    106       // error has happened
    107       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
    108                    "InternalEncode: Encode error for G729_1");
    109       *bitstream_len_byte = 0;
    110       return -1;
    111     }
    112 
    113     num_encoded_samples += 160;
    114   } while (*bitstream_len_byte == 0);
    115 
    116   // This criteria will change if we have Annex C.
    117   if (*bitstream_len_byte != byte_length_frame) {
    118     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
    119                  "InternalEncode: Encode error for G729_1");
    120     *bitstream_len_byte = 0;
    121     return -1;
    122   }
    123 
    124   if (num_encoded_samples != frame_len_smpl_) {
    125     *bitstream_len_byte = 0;
    126     return -1;
    127   }
    128 
    129   return *bitstream_len_byte;
    130 }
    131 
    132 int16_t ACMG729_1::InternalInitEncoder(WebRtcACMCodecParams* codec_params) {
    133   // set the bit rate and initialize
    134   my_rate_ = codec_params->codec_inst.rate;
    135   return SetBitRateSafe((uint32_t)my_rate_);
    136 }
    137 
    138 ACMGenericCodec* ACMG729_1::CreateInstance(void) { return NULL; }
    139 
    140 int16_t ACMG729_1::InternalCreateEncoder() {
    141   if (WebRtcG7291_Create(&encoder_inst_ptr_) < 0) {
    142     WEBRTC_TRACE(webrtc::kTraceError,
    143                  webrtc::kTraceAudioCoding,
    144                  unique_id_,
    145                  "InternalCreateEncoder: create encoder failed for G729_1");
    146     return -1;
    147   }
    148   return 0;
    149 }
    150 
    151 void ACMG729_1::DestructEncoderSafe() {
    152   encoder_exist_ = false;
    153   encoder_initialized_ = false;
    154   if (encoder_inst_ptr_ != NULL) {
    155     WebRtcG7291_Free(encoder_inst_ptr_);
    156     encoder_inst_ptr_ = NULL;
    157   }
    158 }
    159 
    160 int16_t ACMG729_1::SetBitRateSafe(const int32_t rate) {
    161   // allowed rates: { 8000, 12000, 14000, 16000, 18000, 20000,
    162   //                22000, 24000, 26000, 28000, 30000, 32000};
    163   // TODO(tlegrand): This check exists in one other place two. Should be
    164   // possible to reuse code.
    165   switch (rate) {
    166     case 8000: {
    167       my_rate_ = 8000;
    168       break;
    169     }
    170     case 12000: {
    171       my_rate_ = 12000;
    172       break;
    173     }
    174     case 14000: {
    175       my_rate_ = 14000;
    176       break;
    177     }
    178     case 16000: {
    179       my_rate_ = 16000;
    180       break;
    181     }
    182     case 18000: {
    183       my_rate_ = 18000;
    184       break;
    185     }
    186     case 20000: {
    187       my_rate_ = 20000;
    188       break;
    189     }
    190     case 22000: {
    191       my_rate_ = 22000;
    192       break;
    193     }
    194     case 24000: {
    195       my_rate_ = 24000;
    196       break;
    197     }
    198     case 26000: {
    199       my_rate_ = 26000;
    200       break;
    201     }
    202     case 28000: {
    203       my_rate_ = 28000;
    204       break;
    205     }
    206     case 30000: {
    207       my_rate_ = 30000;
    208       break;
    209     }
    210     case 32000: {
    211       my_rate_ = 32000;
    212       break;
    213     }
    214     default: {
    215       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
    216                    "SetBitRateSafe: Invalid rate G729_1");
    217       return -1;
    218     }
    219   }
    220 
    221   // Re-init with new rate
    222   if (WebRtcG7291_EncoderInit(encoder_inst_ptr_, my_rate_, flag_8khz_,
    223                               flag_g729_mode_) >= 0) {
    224     encoder_params_.codec_inst.rate = my_rate_;
    225     return 0;
    226   } else {
    227     return -1;
    228   }
    229 }
    230 
    231 #endif
    232 
    233 }  // namespace acm2
    234 
    235 }  // namespace webrtc
    236