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