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_amr.h" 12 13 #ifdef WEBRTC_CODEC_AMR 14 // NOTE! GSM AMR is not included in the open-source package. The following 15 // interface file is needed: 16 #include "webrtc/modules/audio_coding/main/codecs/amr/interface/amr_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 WebRtcAmr_CreateEnc(AMR_encinst_t_** enc_inst); 25 // int16_t WebRtcAmr_CreateDec(AMR_decinst_t_** dec_inst); 26 // int16_t WebRtcAmr_FreeEnc(AMR_encinst_t_* enc_inst); 27 // int16_t WebRtcAmr_FreeDec(AMR_decinst_t_* dec_inst); 28 // int16_t WebRtcAmr_Encode(AMR_encinst_t_* enc_inst, 29 // int16_t* input, 30 // int16_t len, 31 // int16_t*output, 32 // int16_t mode); 33 // int16_t WebRtcAmr_EncoderInit(AMR_encinst_t_* enc_inst, 34 // int16_t dtx_mode); 35 // int16_t WebRtcAmr_EncodeBitmode(AMR_encinst_t_* enc_inst, 36 // int format); 37 // int16_t WebRtcAmr_Decode(AMR_decinst_t_* dec_inst); 38 // int16_t WebRtcAmr_DecodePlc(AMR_decinst_t_* dec_inst); 39 // int16_t WebRtcAmr_DecoderInit(AMR_decinst_t_* dec_inst); 40 // int16_t WebRtcAmr_DecodeBitmode(AMR_decinst_t_* dec_inst, 41 // int format); 42 #endif 43 44 namespace webrtc { 45 46 namespace acm2 { 47 48 #ifndef WEBRTC_CODEC_AMR 49 ACMAMR::ACMAMR(int16_t /* codec_id */) 50 : encoder_inst_ptr_(NULL), 51 encoding_mode_(-1), // Invalid value. 52 encoding_rate_(0), // Invalid value. 53 encoder_packing_format_(AMRBandwidthEfficient) { 54 return; 55 } 56 57 ACMAMR::~ACMAMR() { return; } 58 59 int16_t ACMAMR::InternalEncode(uint8_t* /* bitstream */, 60 int16_t* /* bitstream_len_byte */) { 61 return -1; 62 } 63 64 int16_t ACMAMR::EnableDTX() { return -1; } 65 66 int16_t ACMAMR::DisableDTX() { return -1; } 67 68 int16_t ACMAMR::InternalInitEncoder(WebRtcACMCodecParams* /* codec_params */) { 69 return -1; 70 } 71 72 ACMGenericCodec* ACMAMR::CreateInstance(void) { return NULL; } 73 74 int16_t ACMAMR::InternalCreateEncoder() { return -1; } 75 76 void ACMAMR::DestructEncoderSafe() { return; } 77 78 int16_t ACMAMR::SetBitRateSafe(const int32_t /* rate */) { return -1; } 79 80 void ACMAMR::InternalDestructEncoderInst(void* /* ptr_inst */) { return; } 81 82 int16_t ACMAMR::SetAMREncoderPackingFormat( 83 ACMAMRPackingFormat /* packing_format */) { 84 return -1; 85 } 86 87 ACMAMRPackingFormat ACMAMR::AMREncoderPackingFormat() const { 88 return AMRUndefined; 89 } 90 91 int16_t ACMAMR::SetAMRDecoderPackingFormat( 92 ACMAMRPackingFormat /* packing_format */) { 93 return -1; 94 } 95 96 ACMAMRPackingFormat ACMAMR::AMRDecoderPackingFormat() const { 97 return AMRUndefined; 98 } 99 100 #else //===================== Actual Implementation ======================= 101 102 #define WEBRTC_AMR_MR475 0 103 #define WEBRTC_AMR_MR515 1 104 #define WEBRTC_AMR_MR59 2 105 #define WEBRTC_AMR_MR67 3 106 #define WEBRTC_AMR_MR74 4 107 #define WEBRTC_AMR_MR795 5 108 #define WEBRTC_AMR_MR102 6 109 #define WEBRTC_AMR_MR122 7 110 111 ACMAMR::ACMAMR(int16_t codec_id) 112 : encoder_inst_ptr_(NULL), 113 encoding_mode_(-1), // invalid value 114 encoding_rate_(0) { // invalid value 115 codec_id_ = codec_id; 116 has_internal_dtx_ = true; 117 encoder_packing_format_ = AMRBandwidthEfficient; 118 return; 119 } 120 121 ACMAMR::~ACMAMR() { 122 if (encoder_inst_ptr_ != NULL) { 123 WebRtcAmr_FreeEnc(encoder_inst_ptr_); 124 encoder_inst_ptr_ = NULL; 125 } 126 return; 127 } 128 129 int16_t ACMAMR::InternalEncode(uint8_t* bitstream, 130 int16_t* bitstream_len_byte) { 131 int16_t vad_decision = 1; 132 // sanity check, if the rate is set correctly. we might skip this 133 // sanity check. if rate is not set correctly, initialization flag 134 // should be false and should not be here. 135 if ((encoding_mode_ < WEBRTC_AMR_MR475) || 136 (encoding_mode_ > WEBRTC_AMR_MR122)) { 137 *bitstream_len_byte = 0; 138 return -1; 139 } 140 *bitstream_len_byte = WebRtcAmr_Encode(encoder_inst_ptr_, 141 &in_audio_[in_audio_ix_read_], 142 frame_len_smpl_, 143 reinterpret_cast<int16_t*>(bitstream), 144 encoding_mode_); 145 146 // Update VAD, if internal DTX is used 147 if (has_internal_dtx_ && dtx_enabled_) { 148 if (*bitstream_len_byte <= (7 * frame_len_smpl_ / 160)) { 149 vad_decision = 0; 150 } 151 for (int16_t n = 0; n < MAX_FRAME_SIZE_10MSEC; n++) { 152 vad_label_[n] = vad_decision; 153 } 154 } 155 // increment the read index 156 in_audio_ix_read_ += frame_len_smpl_; 157 return *bitstream_len_byte; 158 } 159 160 int16_t ACMAMR::EnableDTX() { 161 if (dtx_enabled_) { 162 return 0; 163 } else if (encoder_exist_) { // check if encoder exist 164 // enable DTX 165 if (WebRtcAmr_EncoderInit(encoder_inst_ptr_, 1) < 0) { 166 return -1; 167 } 168 dtx_enabled_ = true; 169 return 0; 170 } else { 171 return -1; 172 } 173 } 174 175 int16_t ACMAMR::DisableDTX() { 176 if (!dtx_enabled_) { 177 return 0; 178 } else if (encoder_exist_) { // check if encoder exist 179 // disable DTX 180 if (WebRtcAmr_EncoderInit(encoder_inst_ptr_, 0) < 0) { 181 return -1; 182 } 183 dtx_enabled_ = false; 184 return 0; 185 } else { 186 // encoder doesn't exists, therefore disabling is harmless 187 return 0; 188 } 189 } 190 191 int16_t ACMAMR::InternalInitEncoder(WebRtcACMCodecParams* codec_params) { 192 int16_t status = SetBitRateSafe((codec_params->codec_inst).rate); 193 status += (WebRtcAmr_EncoderInit(encoder_inst_ptr_, 194 ((codec_params->enable_dtx) ? 1 : 0)) < 0) 195 ? -1 196 : 0; 197 status += 198 (WebRtcAmr_EncodeBitmode(encoder_inst_ptr_, encoder_packing_format_) < 0) 199 ? -1 200 : 0; 201 return (status < 0) ? -1 : 0; 202 } 203 204 ACMGenericCodec* ACMAMR::CreateInstance(void) { return NULL; } 205 206 int16_t ACMAMR::InternalCreateEncoder() { 207 return WebRtcAmr_CreateEnc(&encoder_inst_ptr_); 208 } 209 210 void ACMAMR::DestructEncoderSafe() { 211 if (encoder_inst_ptr_ != NULL) { 212 WebRtcAmr_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; // invalid value 220 } 221 222 int16_t ACMAMR::SetBitRateSafe(const int32_t rate) { 223 switch (rate) { 224 case 4750: { 225 encoding_mode_ = WEBRTC_AMR_MR475; 226 encoding_rate_ = 4750; 227 break; 228 } 229 case 5150: { 230 encoding_mode_ = WEBRTC_AMR_MR515; 231 encoding_rate_ = 5150; 232 break; 233 } 234 case 5900: { 235 encoding_mode_ = WEBRTC_AMR_MR59; 236 encoding_rate_ = 5900; 237 break; 238 } 239 case 6700: { 240 encoding_mode_ = WEBRTC_AMR_MR67; 241 encoding_rate_ = 6700; 242 break; 243 } 244 case 7400: { 245 encoding_mode_ = WEBRTC_AMR_MR74; 246 encoding_rate_ = 7400; 247 break; 248 } 249 case 7950: { 250 encoding_mode_ = WEBRTC_AMR_MR795; 251 encoding_rate_ = 7950; 252 break; 253 } 254 case 10200: { 255 encoding_mode_ = WEBRTC_AMR_MR102; 256 encoding_rate_ = 10200; 257 break; 258 } 259 case 12200: { 260 encoding_mode_ = WEBRTC_AMR_MR122; 261 encoding_rate_ = 12200; 262 break; 263 } 264 default: { 265 return -1; 266 } 267 } 268 return 0; 269 } 270 271 void ACMAMR::InternalDestructEncoderInst(void* ptr_inst) { 272 // Free the memory where ptr_inst is pointing to 273 if (ptr_inst != NULL) { 274 WebRtcAmr_FreeEnc(static_cast<AMR_encinst_t_*>(ptr_inst)); 275 } 276 return; 277 } 278 279 int16_t ACMAMR::SetAMREncoderPackingFormat(ACMAMRPackingFormat packing_format) { 280 if ((packing_format != AMRBandwidthEfficient) && 281 (packing_format != AMROctetAlligned) && 282 (packing_format != AMRFileStorage)) { 283 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, 284 "Invalid AMR Encoder packing-format."); 285 return -1; 286 } else { 287 if (WebRtcAmr_EncodeBitmode(encoder_inst_ptr_, packing_format) < 0) { 288 return -1; 289 } else { 290 encoder_packing_format_ = packing_format; 291 return 0; 292 } 293 } 294 } 295 296 ACMAMRPackingFormat ACMAMR::AMREncoderPackingFormat() const { 297 return encoder_packing_format_; 298 } 299 300 int16_t ACMAMR::SetAMRDecoderPackingFormat( 301 ACMAMRPackingFormat /* packing_format */) { 302 // Not implemented. 303 return -1; 304 } 305 306 ACMAMRPackingFormat ACMAMR::AMRDecoderPackingFormat() const { 307 // Not implemented. 308 return AMRUndefined; 309 } 310 311 #endif 312 } // namespace acm2 313 314 } // namespace webrtc 315