/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/audio_coding/main/source/acm_amrwb.h"

#include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
#include "webrtc/modules/audio_coding/main/source/acm_common_defs.h"
#include "webrtc/modules/audio_coding/main/source/acm_neteq.h"
#include "webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h"
#include "webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h"
#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"

#ifdef WEBRTC_CODEC_AMRWB
// NOTE! GSM AMR-wb is not included in the open-source package. The
// following interface file is needed:
//
// /modules/audio_coding/codecs/amrwb/main/interface/amrwb_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcAmrWb_CreateEnc(AMRWB_encinst_t_** enc_inst);
// int16_t WebRtcAmrWb_CreateDec(AMRWB_decinst_t_** dec_inst);
// int16_t WebRtcAmrWb_FreeEnc(AMRWB_encinst_t_* enc_inst);
// int16_t WebRtcAmrWb_FreeDec(AMRWB_decinst_t_* dec_inst);
// int16_t WebRtcAmrWb_Encode(AMRWB_encinst_t_* enc_inst, int16_t* input,
//                            int16_t len, int16_t* output, int16_t mode);
// int16_t WebRtcAmrWb_EncoderInit(AMRWB_encinst_t_* enc_inst,
//                                 int16_t dtx_mode);
// int16_t WebRtcAmrWb_EncodeBitmode(AMRWB_encinst_t_* enc_inst,
//                                    int format);
// int16_t WebRtcAmrWb_Decode(AMRWB_decinst_t_* dec_inst);
// int16_t WebRtcAmrWb_DecodePlc(AMRWB_decinst_t_* dec_inst);
// int16_t WebRtcAmrWb_DecoderInit(AMRWB_decinst_t_* dec_inst);
// int16_t WebRtcAmrWb_DecodeBitmode(AMRWB_decinst_t_* dec_inst,
//                                   int format);
#include "amrwb_interface.h"
#endif

namespace webrtc {

namespace acm1 {

#ifndef WEBRTC_CODEC_AMRWB
ACMAMRwb::ACMAMRwb(int16_t /* codec_id */)
    : encoder_inst_ptr_(NULL),
      decoder_inst_ptr_(NULL),
      encoding_mode_(-1),  // invalid value
      encoding_rate_(0),  // invalid value
      encoder_packing_format_(AMRBandwidthEfficient),
      decoder_packing_format_(AMRBandwidthEfficient) {
}

ACMAMRwb::~ACMAMRwb() {
}

int16_t ACMAMRwb::InternalEncode(
    uint8_t* /* bitstream */,
    int16_t* /* bitstream_len_byte */) {
  return -1;
}

int16_t ACMAMRwb::DecodeSafe(uint8_t* /* bitstream */,
                             int16_t /* bitstream_len_byte */,
                             int16_t* /* audio */,
                             int16_t* /* audio_samples */,
                             int8_t* /* speech_type */) {
  return -1;
}

int16_t ACMAMRwb::EnableDTX() {
  return -1;
}

int16_t ACMAMRwb::DisableDTX() {
  return -1;
}

int16_t ACMAMRwb::InternalInitEncoder(
    WebRtcACMCodecParams* /* codec_params */) {
  return -1;
}

int16_t ACMAMRwb::InternalInitDecoder(
    WebRtcACMCodecParams* /* codec_params */) {
  return -1;
}

int32_t ACMAMRwb::CodecDef(WebRtcNetEQ_CodecDef& /* codec_def */,
                           const CodecInst& /* codec_inst */) {
  return -1;
}

ACMGenericCodec*
ACMAMRwb::CreateInstance(void) {
  return NULL;
}

int16_t ACMAMRwb::InternalCreateEncoder() {
  return -1;
}

void ACMAMRwb::DestructEncoderSafe() {
  return;
}

int16_t ACMAMRwb::InternalCreateDecoder() {
  return -1;
}

void ACMAMRwb::DestructDecoderSafe() {
  return;
}

int16_t ACMAMRwb::SetBitRateSafe(const int32_t /* rate */) {
  return -1;
}

void ACMAMRwb::InternalDestructEncoderInst(void* /* ptr_inst */) {
  return;
}

int16_t ACMAMRwb::SetAMRwbEncoderPackingFormat(
    ACMAMRPackingFormat /* packing_format */) {
  return -1;
}

ACMAMRPackingFormat ACMAMRwb::AMRwbEncoderPackingFormat() const {
  return AMRUndefined;
}

int16_t ACMAMRwb::SetAMRwbDecoderPackingFormat(
    ACMAMRPackingFormat /* packing_format */) {
  return -1;
}

ACMAMRPackingFormat ACMAMRwb::AMRwbDecoderPackingFormat() const {
  return AMRUndefined;
}

#else     //===================== Actual Implementation =======================

#define AMRWB_MODE_7k       0
#define AMRWB_MODE_9k       1
#define AMRWB_MODE_12k      2
#define AMRWB_MODE_14k      3
#define AMRWB_MODE_16k      4
#define AMRWB_MODE_18k      5
#define AMRWB_MODE_20k      6
#define AMRWB_MODE_23k      7
#define AMRWB_MODE_24k      8

ACMAMRwb::ACMAMRwb(int16_t codec_id)
    : encoder_inst_ptr_(NULL),
      decoder_inst_ptr_(NULL),
      encoding_mode_(-1),  // invalid value
      encoding_rate_(0) {  // invalid value
  codec_id_ = codec_id;
  has_internal_dtx_ = true;
  encoder_packing_format_ = AMRBandwidthEfficient;
  decoder_packing_format_ = AMRBandwidthEfficient;
  return;
}

ACMAMRwb::~ACMAMRwb() {
  if (encoder_inst_ptr_ != NULL) {
    WebRtcAmrWb_FreeEnc(encoder_inst_ptr_);
    encoder_inst_ptr_ = NULL;
  }
  if (decoder_inst_ptr_ != NULL) {
    WebRtcAmrWb_FreeDec(decoder_inst_ptr_);
    decoder_inst_ptr_ = NULL;
  }
  return;
}

int16_t ACMAMRwb::InternalEncode(uint8_t* bitstream,
                                 int16_t* bitstream_len_byte) {
  int16_t vad_decision = 1;
  // sanity check, if the rate is set correctly. we might skip this
  // sanity check. if rate is not set correctly, initialization flag
  // should be false and should not be here.
  if ((encoding_mode_ < AMRWB_MODE_7k) || (encoding_mode_ > AMRWB_MODE_24k)) {
    *bitstream_len_byte = 0;
    return -1;
  }
  *bitstream_len_byte = WebRtcAmrWb_Encode(encoder_inst_ptr_,
                                           &in_audio_[in_audio_ix_read_],
                                           frame_len_smpl_,
                                           (int16_t*)bitstream,
                                           encoding_mode_);

  // Update VAD, if internal DTX is used
  if (has_internal_dtx_ && dtx_enabled_) {
    if (*bitstream_len_byte <= (7 * frame_len_smpl_ / 160)) {
      vad_decision = 0;
    }
    for (int16_t n = 0; n < MAX_FRAME_SIZE_10MSEC; n++) {
      vad_label_[n] = vad_decision;
    }
  }
  // increment the read index this tell the caller that how far
  // we have gone forward in reading the audio buffer
  in_audio_ix_read_ += frame_len_smpl_;
  return *bitstream_len_byte;
}

int16_t ACMAMRwb::DecodeSafe(uint8_t* /* bitstream */,
                             int16_t /* bitstream_len_byte */,
                             int16_t* /* audio */,
                             int16_t* /* audio_samples */,
                             int8_t* /* speech_type */) {
  return 0;
}

int16_t ACMAMRwb::EnableDTX() {
  if (dtx_enabled_) {
    return 0;
  } else if (encoder_exist_) {  // check if encoder exist
    // enable DTX
    if (WebRtcAmrWb_EncoderInit(encoder_inst_ptr_, 1) < 0) {
      return -1;
    }
    dtx_enabled_ = true;
    return 0;
  } else {
    return -1;
  }
}

int16_t ACMAMRwb::DisableDTX() {
  if (!dtx_enabled_) {
    return 0;
  } else if (encoder_exist_) {  // check if encoder exist
    // disable DTX
    if (WebRtcAmrWb_EncoderInit(encoder_inst_ptr_, 0) < 0) {
      return -1;
    }
    dtx_enabled_ = false;
    return 0;
  } else {
    // encoder doesn't exists, therefore disabling is harmless
    return 0;
  }
}

int16_t ACMAMRwb::InternalInitEncoder(
    WebRtcACMCodecParams* codec_params) {
  // sanity check
  if (encoder_inst_ptr_ == NULL) {
    return -1;
  }

  int16_t status = SetBitRateSafe((codec_params->codec_inst).rate);
  status += (WebRtcAmrWb_EncoderInit(
      encoder_inst_ptr_, ((codec_params->enable_dtx) ? 1 : 0)) < 0) ? -1 : 0;
  status += (WebRtcAmrWb_EncodeBitmode(
      encoder_inst_ptr_, encoder_packing_format_) < 0) ? -1 : 0;
  return (status < 0) ? -1 : 0;
}

int16_t ACMAMRwb::InternalInitDecoder(
    WebRtcACMCodecParams* /* codec_params */) {
  int16_t status = WebRtcAmrWb_DecodeBitmode(decoder_inst_ptr_,
                                                   decoder_packing_format_);
  status += ((WebRtcAmrWb_DecoderInit(decoder_inst_ptr_) < 0) ? -1 : 0);
  return (status < 0) ? -1 : 0;
}

int32_t ACMAMRwb::CodecDef(WebRtcNetEQ_CodecDef& codec_def,
                           const CodecInst& codec_inst) {
  if (!decoder_initialized_) {
    return -1;
  }

  // Fill up the structure by calling
  // "SET_CODEC_PAR" & "SET_AMRWB_FUNCTION."
  // Then call NetEQ to add the codec to it's
  // database.
  SET_CODEC_PAR((codec_def), kDecoderAMRWB, codec_inst.pltype,
                decoder_inst_ptr_, 16000);
  SET_AMRWB_FUNCTIONS((codec_def));
  return 0;
}

ACMGenericCodec* ACMAMRwb::CreateInstance(void) {
  return NULL;
}

int16_t ACMAMRwb::InternalCreateEncoder() {
  return WebRtcAmrWb_CreateEnc(&encoder_inst_ptr_);
}

void ACMAMRwb::DestructEncoderSafe() {
  if (encoder_inst_ptr_ != NULL) {
    WebRtcAmrWb_FreeEnc(encoder_inst_ptr_);
    encoder_inst_ptr_ = NULL;
  }
  // there is no encoder set the following
  encoder_exist_ = false;
  encoder_initialized_ = false;
  encoding_mode_ = -1;  // invalid value
  encoding_rate_ = 0;
}

int16_t ACMAMRwb::InternalCreateDecoder() {
  return WebRtcAmrWb_CreateDec(&decoder_inst_ptr_);
}

void ACMAMRwb::DestructDecoderSafe() {
  if (decoder_inst_ptr_ != NULL) {
    WebRtcAmrWb_FreeDec(decoder_inst_ptr_);
    decoder_inst_ptr_ = NULL;
  }
  // there is no encoder instance set the followings
  decoder_exist_ = false;
  decoder_initialized_ = false;
}

int16_t ACMAMRwb::SetBitRateSafe(const int32_t rate) {
  switch (rate) {
    case 7000: {
      encoding_mode_ = AMRWB_MODE_7k;
      encoding_rate_ = 7000;
      break;
    }
    case 9000: {
      encoding_mode_ = AMRWB_MODE_9k;
      encoding_rate_ = 9000;
      break;
    }
    case 12000: {
      encoding_mode_ = AMRWB_MODE_12k;
      encoding_rate_ = 12000;
      break;
    }
    case 14000: {
      encoding_mode_ = AMRWB_MODE_14k;
      encoding_rate_ = 14000;
      break;
    }
    case 16000: {
      encoding_mode_ = AMRWB_MODE_16k;
      encoding_rate_ = 16000;
      break;
    }
    case 18000: {
      encoding_mode_ = AMRWB_MODE_18k;
      encoding_rate_ = 18000;
      break;
    }
    case 20000: {
      encoding_mode_ = AMRWB_MODE_20k;
      encoding_rate_ = 20000;
      break;
    }
    case 23000: {
      encoding_mode_ = AMRWB_MODE_23k;
      encoding_rate_ = 23000;
      break;
    }
    case 24000: {
      encoding_mode_ = AMRWB_MODE_24k;
      encoding_rate_ = 24000;
      break;
    }
    default: {
      return -1;
    }
  }
  return 0;
}

void ACMAMRwb::InternalDestructEncoderInst(void* ptr_inst) {
  if (ptr_inst != NULL) {
    WebRtcAmrWb_FreeEnc(static_cast<AMRWB_encinst_t_*>(ptr_inst));
  }
  return;
}

int16_t ACMAMRwb::SetAMRwbEncoderPackingFormat(
    ACMAMRPackingFormat packing_format) {
  if ((packing_format != AMRBandwidthEfficient) &&
      (packing_format != AMROctetAlligned) &&
      (packing_format != AMRFileStorage)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
                 "Invalid AMRwb encoder packing-format.");
    return -1;
  } else {
    if (WebRtcAmrWb_EncodeBitmode(encoder_inst_ptr_, packing_format) < 0) {
      return -1;
    } else {
      encoder_packing_format_ = packing_format;
      return 0;
    }
  }
}

ACMAMRPackingFormat ACMAMRwb::AMRwbEncoderPackingFormat() const {
  return encoder_packing_format_;
}

int16_t ACMAMRwb::SetAMRwbDecoderPackingFormat(
    ACMAMRPackingFormat packing_format) {
  if ((packing_format != AMRBandwidthEfficient) &&
      (packing_format != AMROctetAlligned) &&
      (packing_format != AMRFileStorage)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
                 "Invalid AMRwb decoder packing-format.");
    return -1;
  } else {
    if (WebRtcAmrWb_DecodeBitmode(decoder_inst_ptr_, packing_format) < 0) {
      return -1;
    } else {
      decoder_packing_format_ = packing_format;
      return 0;
    }
  }
}

ACMAMRPackingFormat ACMAMRwb::AMRwbDecoderPackingFormat() const {
  return decoder_packing_format_;
}

#endif

}  // namespace acm1

}  // namespace webrtc
