/*
 *  Copyright (c) 2011 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.
 */

#ifndef MODULES_AUDIO_DEVICE_INCLUDE_AUDIO_DEVICE_DEFINES_H_
#define MODULES_AUDIO_DEVICE_INCLUDE_AUDIO_DEVICE_DEFINES_H_

#include <stddef.h>

#include <string>

#include "rtc_base/checks.h"
#include "rtc_base/deprecation.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {

static const int kAdmMaxDeviceNameSize = 128;
static const int kAdmMaxFileNameSize = 512;
static const int kAdmMaxGuidSize = 128;

static const int kAdmMinPlayoutBufferSizeMs = 10;
static const int kAdmMaxPlayoutBufferSizeMs = 250;

// ----------------------------------------------------------------------------
//  AudioTransport
// ----------------------------------------------------------------------------

class AudioTransport {
 public:
  virtual int32_t RecordedDataIsAvailable(const void* audioSamples,
                                          const size_t nSamples,
                                          const size_t nBytesPerSample,
                                          const size_t nChannels,
                                          const uint32_t samplesPerSec,
                                          const uint32_t totalDelayMS,
                                          const int32_t clockDrift,
                                          const uint32_t currentMicLevel,
                                          const bool keyPressed,
                                          uint32_t& newMicLevel) = 0;  // NOLINT

  // Implementation has to setup safe values for all specified out parameters.
  virtual int32_t NeedMorePlayData(const size_t nSamples,
                                   const size_t nBytesPerSample,
                                   const size_t nChannels,
                                   const uint32_t samplesPerSec,
                                   void* audioSamples,
                                   size_t& nSamplesOut,  // NOLINT
                                   int64_t* elapsed_time_ms,
                                   int64_t* ntp_time_ms) = 0;  // NOLINT

  // Method to pull mixed render audio data from all active VoE channels.
  // The data will not be passed as reference for audio processing internally.
  virtual void PullRenderData(int bits_per_sample,
                              int sample_rate,
                              size_t number_of_channels,
                              size_t number_of_frames,
                              void* audio_data,
                              int64_t* elapsed_time_ms,
                              int64_t* ntp_time_ms) = 0;

 protected:
  virtual ~AudioTransport() {}
};

// Helper class for storage of fundamental audio parameters such as sample rate,
// number of channels, native buffer size etc.
// Note that one audio frame can contain more than one channel sample and each
// sample is assumed to be a 16-bit PCM sample. Hence, one audio frame in
// stereo contains 2 * (16/8) = 4 bytes of data.
class AudioParameters {
 public:
  // This implementation does only support 16-bit PCM samples.
  static const size_t kBitsPerSample = 16;
  AudioParameters()
      : sample_rate_(0),
        channels_(0),
        frames_per_buffer_(0),
        frames_per_10ms_buffer_(0) {}
  AudioParameters(int sample_rate, size_t channels, size_t frames_per_buffer)
      : sample_rate_(sample_rate),
        channels_(channels),
        frames_per_buffer_(frames_per_buffer),
        frames_per_10ms_buffer_(static_cast<size_t>(sample_rate / 100)) {}
  void reset(int sample_rate, size_t channels, size_t frames_per_buffer) {
    sample_rate_ = sample_rate;
    channels_ = channels;
    frames_per_buffer_ = frames_per_buffer;
    frames_per_10ms_buffer_ = static_cast<size_t>(sample_rate / 100);
  }
  size_t bits_per_sample() const { return kBitsPerSample; }
  void reset(int sample_rate, size_t channels, double ms_per_buffer) {
    reset(sample_rate, channels,
          static_cast<size_t>(sample_rate * ms_per_buffer + 0.5));
  }
  void reset(int sample_rate, size_t channels) {
    reset(sample_rate, channels, static_cast<size_t>(0));
  }
  int sample_rate() const { return sample_rate_; }
  size_t channels() const { return channels_; }
  size_t frames_per_buffer() const { return frames_per_buffer_; }
  size_t frames_per_10ms_buffer() const { return frames_per_10ms_buffer_; }
  size_t GetBytesPerFrame() const { return channels_ * kBitsPerSample / 8; }
  size_t GetBytesPerBuffer() const {
    return frames_per_buffer_ * GetBytesPerFrame();
  }
  // The WebRTC audio device buffer (ADB) only requires that the sample rate
  // and number of channels are configured. Hence, to be "valid", only these
  // two attributes must be set.
  bool is_valid() const { return ((sample_rate_ > 0) && (channels_ > 0)); }
  // Most platforms also require that a native buffer size is defined.
  // An audio parameter instance is considered to be "complete" if it is both
  // "valid" (can be used by the ADB) and also has a native frame size.
  bool is_complete() const { return (is_valid() && (frames_per_buffer_ > 0)); }
  size_t GetBytesPer10msBuffer() const {
    return frames_per_10ms_buffer_ * GetBytesPerFrame();
  }
  double GetBufferSizeInMilliseconds() const {
    if (sample_rate_ == 0)
      return 0.0;
    return frames_per_buffer_ / (sample_rate_ / 1000.0);
  }
  double GetBufferSizeInSeconds() const {
    if (sample_rate_ == 0)
      return 0.0;
    return static_cast<double>(frames_per_buffer_) / (sample_rate_);
  }
  std::string ToString() const {
    char ss_buf[1024];
    rtc::SimpleStringBuilder ss(ss_buf);
    ss << "AudioParameters: ";
    ss << "sample_rate=" << sample_rate() << ", channels=" << channels();
    ss << ", frames_per_buffer=" << frames_per_buffer();
    ss << ", frames_per_10ms_buffer=" << frames_per_10ms_buffer();
    ss << ", bytes_per_frame=" << GetBytesPerFrame();
    ss << ", bytes_per_buffer=" << GetBytesPerBuffer();
    ss << ", bytes_per_10ms_buffer=" << GetBytesPer10msBuffer();
    ss << ", size_in_ms=" << GetBufferSizeInMilliseconds();
    return ss.str();
  }

 private:
  int sample_rate_;
  size_t channels_;
  size_t frames_per_buffer_;
  size_t frames_per_10ms_buffer_;
};

}  // namespace webrtc

#endif  // MODULES_AUDIO_DEVICE_INCLUDE_AUDIO_DEVICE_DEFINES_H_
