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_g722.h"
     12 
     13 #ifdef WEBRTC_CODEC_G722
     14 #include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.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/system_wrappers/interface/trace.h"
     18 #endif
     19 
     20 namespace webrtc {
     21 
     22 namespace acm2 {
     23 
     24 #ifndef WEBRTC_CODEC_G722
     25 
     26 ACMG722::ACMG722(int16_t /* codec_id */)
     27     : ptr_enc_str_(NULL),
     28       encoder_inst_ptr_(NULL),
     29       encoder_inst_ptr_right_(NULL) {}
     30 
     31 ACMG722::~ACMG722() {}
     32 
     33 int32_t ACMG722::Add10MsDataSafe(const uint32_t /* timestamp */,
     34                                  const int16_t* /* data */,
     35                                  const uint16_t /* length_smpl */,
     36                                  const uint8_t /* audio_channel */) {
     37   return -1;
     38 }
     39 
     40 int16_t ACMG722::InternalEncode(uint8_t* /* bitstream */,
     41                                 int16_t* /* bitstream_len_byte */) {
     42   return -1;
     43 }
     44 
     45 int16_t ACMG722::InternalInitEncoder(WebRtcACMCodecParams* /* codec_params */) {
     46   return -1;
     47 }
     48 
     49 ACMGenericCodec* ACMG722::CreateInstance(void) { return NULL; }
     50 
     51 int16_t ACMG722::InternalCreateEncoder() { return -1; }
     52 
     53 void ACMG722::DestructEncoderSafe() { return; }
     54 
     55 void ACMG722::InternalDestructEncoderInst(void* /* ptr_inst */) { return; }
     56 
     57 #else     //===================== Actual Implementation =======================
     58 
     59 // Encoder and decoder memory
     60 struct ACMG722EncStr {
     61   G722EncInst* inst;  // instance for left channel in case of stereo
     62   G722EncInst* inst_right;  // instance for right channel in case of stereo
     63 };
     64 struct ACMG722DecStr {
     65   G722DecInst* inst;  // instance for left channel in case of stereo
     66   G722DecInst* inst_right;  // instance for right channel in case of stereo
     67 };
     68 
     69 ACMG722::ACMG722(int16_t codec_id)
     70     : encoder_inst_ptr_(NULL), encoder_inst_ptr_right_(NULL) {
     71   ptr_enc_str_ = new ACMG722EncStr;
     72   if (ptr_enc_str_ != NULL) {
     73     ptr_enc_str_->inst = NULL;
     74     ptr_enc_str_->inst_right = NULL;
     75   }
     76   codec_id_ = codec_id;
     77   return;
     78 }
     79 
     80 ACMG722::~ACMG722() {
     81   // Encoder
     82   if (ptr_enc_str_ != NULL) {
     83     if (ptr_enc_str_->inst != NULL) {
     84       WebRtcG722_FreeEncoder(ptr_enc_str_->inst);
     85       ptr_enc_str_->inst = NULL;
     86     }
     87     if (ptr_enc_str_->inst_right != NULL) {
     88       WebRtcG722_FreeEncoder(ptr_enc_str_->inst_right);
     89       ptr_enc_str_->inst_right = NULL;
     90     }
     91     delete ptr_enc_str_;
     92     ptr_enc_str_ = NULL;
     93   }
     94   return;
     95 }
     96 
     97 int32_t ACMG722::Add10MsDataSafe(const uint32_t timestamp,
     98                                  const int16_t* data,
     99                                  const uint16_t length_smpl,
    100                                  const uint8_t audio_channel) {
    101   return ACMGenericCodec::Add10MsDataSafe(
    102       (timestamp >> 1), data, length_smpl, audio_channel);
    103 }
    104 
    105 int16_t ACMG722::InternalEncode(uint8_t* bitstream,
    106                                 int16_t* bitstream_len_byte) {
    107   // If stereo, split input signal in left and right channel before encoding
    108   if (num_channels_ == 2) {
    109     int16_t left_channel[960];
    110     int16_t right_channel[960];
    111     uint8_t out_left[480];
    112     uint8_t out_right[480];
    113     int16_t len_in_bytes;
    114     for (int i = 0, j = 0; i < frame_len_smpl_ * 2; i += 2, j++) {
    115       left_channel[j] = in_audio_[in_audio_ix_read_ + i];
    116       right_channel[j] = in_audio_[in_audio_ix_read_ + i + 1];
    117     }
    118     len_in_bytes = WebRtcG722_Encode(
    119         encoder_inst_ptr_, left_channel, frame_len_smpl_,
    120         reinterpret_cast<int16_t*>(out_left));
    121     len_in_bytes += WebRtcG722_Encode(encoder_inst_ptr_right_,
    122                                       right_channel,
    123                                       frame_len_smpl_,
    124                                       reinterpret_cast<int16_t*>(out_right));
    125     *bitstream_len_byte = len_in_bytes;
    126 
    127     // Interleave the 4 bits per sample from left and right channel
    128     for (int i = 0, j = 0; i < len_in_bytes; i += 2, j++) {
    129       bitstream[i] = (out_left[j] & 0xF0) + (out_right[j] >> 4);
    130       bitstream[i + 1] = ((out_left[j] & 0x0F) << 4) + (out_right[j] & 0x0F);
    131     }
    132   } else {
    133     *bitstream_len_byte = WebRtcG722_Encode(
    134         encoder_inst_ptr_, &in_audio_[in_audio_ix_read_], frame_len_smpl_,
    135         reinterpret_cast<int16_t*>(bitstream));
    136   }
    137 
    138   // increment the read index this tell the caller how far
    139   // we have gone forward in reading the audio buffer
    140   in_audio_ix_read_ += frame_len_smpl_ * num_channels_;
    141   return *bitstream_len_byte;
    142 }
    143 
    144 int16_t ACMG722::InternalInitEncoder(WebRtcACMCodecParams* codec_params) {
    145   if (codec_params->codec_inst.channels == 2) {
    146     // Create codec struct for right channel
    147     if (ptr_enc_str_->inst_right == NULL) {
    148       WebRtcG722_CreateEncoder(&ptr_enc_str_->inst_right);
    149       if (ptr_enc_str_->inst_right == NULL) {
    150         return -1;
    151       }
    152     }
    153     encoder_inst_ptr_right_ = ptr_enc_str_->inst_right;
    154     if (WebRtcG722_EncoderInit(encoder_inst_ptr_right_) < 0) {
    155       return -1;
    156     }
    157   }
    158 
    159   return WebRtcG722_EncoderInit(encoder_inst_ptr_);
    160 }
    161 
    162 ACMGenericCodec* ACMG722::CreateInstance(void) { return NULL; }
    163 
    164 int16_t ACMG722::InternalCreateEncoder() {
    165   if (ptr_enc_str_ == NULL) {
    166     // this structure must be created at the costructor
    167     // if it is still NULL then there is a probelm and
    168     // we dont continue
    169     return -1;
    170   }
    171   WebRtcG722_CreateEncoder(&ptr_enc_str_->inst);
    172   if (ptr_enc_str_->inst == NULL) {
    173     return -1;
    174   }
    175   encoder_inst_ptr_ = ptr_enc_str_->inst;
    176   return 0;
    177 }
    178 
    179 void ACMG722::DestructEncoderSafe() {
    180   if (ptr_enc_str_ != NULL) {
    181     if (ptr_enc_str_->inst != NULL) {
    182       WebRtcG722_FreeEncoder(ptr_enc_str_->inst);
    183       ptr_enc_str_->inst = NULL;
    184     }
    185   }
    186   encoder_exist_ = false;
    187   encoder_initialized_ = false;
    188 }
    189 
    190 void ACMG722::InternalDestructEncoderInst(void* ptr_inst) {
    191   if (ptr_inst != NULL) {
    192     WebRtcG722_FreeEncoder(static_cast<G722EncInst*>(ptr_inst));
    193   }
    194   return;
    195 }
    196 
    197 #endif
    198 
    199 }  // namespace acm2
    200 
    201 }  // namespace webrtc
    202