/*
 *  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/interface/audio_coding_module.h"

#include "webrtc/base/checks.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
#include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/trace.h"

namespace webrtc {

// Create module
AudioCodingModule* AudioCodingModule::Create(int id) {
  Config config;
  config.id = id;
  config.clock = Clock::GetRealTimeClock();
  return Create(config);
}

AudioCodingModule* AudioCodingModule::Create(int id, Clock* clock) {
  Config config;
  config.id = id;
  config.clock = clock;
  return Create(config);
}

AudioCodingModule* AudioCodingModule::Create(const Config& config) {
  return new acm2::AudioCodingModuleImpl(config);
}

// Get number of supported codecs
int AudioCodingModule::NumberOfCodecs() {
  return acm2::ACMCodecDB::kNumCodecs;
}

// Get supported codec parameters with id
int AudioCodingModule::Codec(int list_id, CodecInst* codec) {
  // Get the codec settings for the codec with the given list ID
  return acm2::ACMCodecDB::Codec(list_id, codec);
}

// Get supported codec parameters with name, frequency and number of channels.
int AudioCodingModule::Codec(const char* payload_name,
                             CodecInst* codec,
                             int sampling_freq_hz,
                             int channels) {
  int codec_id;

  // Get the id of the codec from the database.
  codec_id = acm2::ACMCodecDB::CodecId(
      payload_name, sampling_freq_hz, channels);
  if (codec_id < 0) {
    // We couldn't find a matching codec, set the parameters to unacceptable
    // values and return.
    codec->plname[0] = '\0';
    codec->pltype = -1;
    codec->pacsize = 0;
    codec->rate = 0;
    codec->plfreq = 0;
    return -1;
  }

  // Get default codec settings.
  acm2::ACMCodecDB::Codec(codec_id, codec);

  // Keep the number of channels from the function call. For most codecs it
  // will be the same value as in default codec settings, but not for all.
  codec->channels = channels;

  return 0;
}

// Get supported codec Index with name, frequency and number of channels.
int AudioCodingModule::Codec(const char* payload_name,
                             int sampling_freq_hz,
                             int channels) {
  return acm2::ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels);
}

// Checks the validity of the parameters of the given codec
bool AudioCodingModule::IsCodecValid(const CodecInst& codec) {
  int codec_number = acm2::ACMCodecDB::CodecNumber(codec);

  if (codec_number < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, -1,
                 "Invalid codec setting");
    return false;
  } else {
    return true;
  }
}

AudioCoding::Config::Config()
    : neteq_config(),
      clock(Clock::GetRealTimeClock()),
      transport(nullptr),
      vad_callback(nullptr),
      initial_playout_delay_ms(0),
      playout_channels(1),
      playout_frequency_hz(32000) {
}

AudioCoding* AudioCoding::Create(const Config& config) {
  return new AudioCodingImpl(config);
}

}  // namespace webrtc
