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