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_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