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_celt.h" 12 13 #ifdef WEBRTC_CODEC_CELT 14 // NOTE! Celt is not included in the open-source package. Modify this file or 15 // your codec API to match the function call and name of used CELT API file. 16 #include "webrtc/modules/audio_coding/codecs/celt/include/celt_interface.h" 17 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" 18 #include "webrtc/system_wrappers/interface/trace.h" 19 #endif 20 21 namespace webrtc { 22 23 namespace acm2 { 24 25 #ifndef WEBRTC_CODEC_CELT 26 27 ACMCELT::ACMCELT(int16_t /* codec_id */) 28 : enc_inst_ptr_(NULL), 29 sampling_freq_(0), 30 bitrate_(0), 31 channels_(1) { 32 return; 33 } 34 35 ACMCELT::~ACMCELT() { 36 return; 37 } 38 39 int16_t ACMCELT::InternalEncode(uint8_t* /* bitstream */, 40 int16_t* /* bitstream_len_byte */) { 41 return -1; 42 } 43 44 int16_t ACMCELT::InternalInitEncoder(WebRtcACMCodecParams* /* codec_params */) { 45 return -1; 46 } 47 48 ACMGenericCodec* ACMCELT::CreateInstance(void) { 49 return NULL; 50 } 51 52 int16_t ACMCELT::InternalCreateEncoder() { 53 return -1; 54 } 55 56 void ACMCELT::DestructEncoderSafe() { 57 return; 58 } 59 60 void ACMCELT::InternalDestructEncoderInst(void* /* ptr_inst */) { 61 return; 62 } 63 64 int16_t ACMCELT::SetBitRateSafe(const int32_t /*rate*/) { 65 return -1; 66 } 67 68 #else //===================== Actual Implementation ======================= 69 70 ACMCELT::ACMCELT(int16_t codec_id) 71 : enc_inst_ptr_(NULL), 72 sampling_freq_(32000), // Default sampling frequency. 73 bitrate_(64000), // Default rate. 74 channels_(1) { // Default send mono. 75 // TODO(tlegrand): remove later when ACMGenericCodec has a new constructor. 76 codec_id_ = codec_id; 77 78 return; 79 } 80 81 ACMCELT::~ACMCELT() { 82 if (enc_inst_ptr_ != NULL) { 83 WebRtcCelt_FreeEnc(enc_inst_ptr_); 84 enc_inst_ptr_ = NULL; 85 } 86 return; 87 } 88 89 int16_t ACMCELT::InternalEncode(uint8_t* bitstream, 90 int16_t* bitstream_len_byte) { 91 *bitstream_len_byte = 0; 92 93 // Call Encoder. 94 *bitstream_len_byte = WebRtcCelt_Encode(enc_inst_ptr_, 95 &in_audio_[in_audio_ix_read_], 96 bitstream); 97 98 // Increment the read index this tell the caller that how far 99 // we have gone forward in reading the audio buffer. 100 in_audio_ix_read_ += frame_len_smpl_ * channels_; 101 102 if (*bitstream_len_byte < 0) { 103 // Error reported from the encoder. 104 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, 105 "InternalEncode: Encode error for Celt"); 106 *bitstream_len_byte = 0; 107 return -1; 108 } 109 110 return *bitstream_len_byte; 111 } 112 113 int16_t ACMCELT::InternalInitEncoder(WebRtcACMCodecParams* codec_params) { 114 // Set bitrate and check that it is within the valid range. 115 int16_t status = SetBitRateSafe((codec_params->codec_inst).rate); 116 if (status < 0) { 117 return -1; 118 } 119 120 // If number of channels changed we need to re-create memory. 121 if (codec_params->codec_inst.channels != channels_) { 122 WebRtcCelt_FreeEnc(enc_inst_ptr_); 123 enc_inst_ptr_ = NULL; 124 // Store new number of channels. 125 channels_ = codec_params->codec_inst.channels; 126 if (WebRtcCelt_CreateEnc(&enc_inst_ptr_, channels_) < 0) { 127 return -1; 128 } 129 } 130 131 // Initiate encoder. 132 if (WebRtcCelt_EncoderInit(enc_inst_ptr_, channels_, bitrate_) >= 0) { 133 return 0; 134 } else { 135 return -1; 136 } 137 } 138 139 ACMGenericCodec* ACMCELT::CreateInstance(void) { 140 return NULL; 141 } 142 143 int16_t ACMCELT::InternalCreateEncoder() { 144 if (WebRtcCelt_CreateEnc(&enc_inst_ptr_, num_channels_) < 0) { 145 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, 146 "InternalCreateEncoder: create encoder failed for Celt"); 147 return -1; 148 } 149 channels_ = num_channels_; 150 return 0; 151 } 152 153 void ACMCELT::DestructEncoderSafe() { 154 encoder_exist_ = false; 155 encoder_initialized_ = false; 156 if (enc_inst_ptr_ != NULL) { 157 WebRtcCelt_FreeEnc(enc_inst_ptr_); 158 enc_inst_ptr_ = NULL; 159 } 160 } 161 162 void ACMCELT::InternalDestructEncoderInst(void* ptr_inst) { 163 if (ptr_inst != NULL) { 164 WebRtcCelt_FreeEnc(static_cast<CELT_encinst_t*>(ptr_inst)); 165 } 166 return; 167 } 168 169 int16_t ACMCELT::SetBitRateSafe(const int32_t rate) { 170 // Check that rate is in the valid range. 171 if ((rate >= 48000) && (rate <= 128000)) { 172 // Store new rate. 173 bitrate_ = rate; 174 175 // Initiate encoder with new rate. 176 if (WebRtcCelt_EncoderInit(enc_inst_ptr_, channels_, bitrate_) >= 0) { 177 return 0; 178 } else { 179 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, 180 "SetBitRateSafe: Failed to initiate Celt with rate %d", 181 rate); 182 return -1; 183 } 184 } else { 185 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, 186 "SetBitRateSafe: Invalid rate Celt, %d", rate); 187 return -1; 188 } 189 } 190 191 #endif 192 193 } // namespace acm2 194 195 } // namespace webrtc 196