// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// MSVC++ requires this to be set before any other includes to get M_PI.
#define _USE_MATH_DEFINES

#include "media/audio/simple_sources.h"

#include <stddef.h>

#include <algorithm>
#include <cmath>

#include "base/files/file.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "media/audio/sounds/wav_audio_handler.h"
#include "media/base/audio_bus.h"

namespace media {
namespace {
// Opens |wav_filename|, reads it and loads it as a wav file. This function will
// return a null pointer if we can't read the file or if it's malformed. The
// caller takes ownership of the returned data. The size of the data is stored
// in |read_length|.
std::unique_ptr<char[]> ReadWavFile(const base::FilePath& wav_filename,
                                    size_t* read_length) {
  base::File wav_file(
      wav_filename, base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!wav_file.IsValid()) {
    LOG(ERROR) << "Failed to read " << wav_filename.value()
               << " as input to the fake device.";
    return nullptr;
  }

  int64_t wav_file_length = wav_file.GetLength();
  if (wav_file_length < 0) {
    LOG(ERROR) << "Failed to get size of " << wav_filename.value();
    return nullptr;
  }
  if (wav_file_length == 0) {
    LOG(ERROR) << "Input file to fake device is empty: "
               << wav_filename.value();
    return nullptr;
  }

  std::unique_ptr<char[]> data(new char[wav_file_length]);
  int read_bytes = wav_file.Read(0, data.get(), wav_file_length);
  if (read_bytes != wav_file_length) {
    LOG(ERROR) << "Failed to read all bytes of " << wav_filename.value();
    return nullptr;
  }
  *read_length = wav_file_length;
  return data;
}

// These values are based on experiments for local-to-local
// PeerConnection to demonstrate audio/video synchronization.
static const int kBeepDurationMilliseconds = 20;
static const int kBeepFrequency = 400;

// Intervals between two automatic beeps.
static const int kAutomaticBeepIntervalInMs = 500;

// Automatic beep will be triggered every |kAutomaticBeepIntervalInMs| unless
// users explicitly call BeepOnce(), which will disable the automatic beep.
class BeepContext {
 public:
  BeepContext() : beep_once_(false), automatic_beep_(true) {}

  void SetBeepOnce(bool enable) {
    base::AutoLock auto_lock(lock_);
    beep_once_ = enable;

    // Disable the automatic beep if users explicit set |beep_once_| to true.
    if (enable)
      automatic_beep_ = false;
  }

  bool beep_once() const {
    base::AutoLock auto_lock(lock_);
    return beep_once_;
  }

  bool automatic_beep() const {
    base::AutoLock auto_lock(lock_);
    return automatic_beep_;
  }

 private:
  mutable base::Lock lock_;
  bool beep_once_;
  bool automatic_beep_;
};

BeepContext* GetBeepContext() {
  static BeepContext* context = new BeepContext();
  return context;
}

}  // namespace

//////////////////////////////////////////////////////////////////////////////
// SineWaveAudioSource implementation.

SineWaveAudioSource::SineWaveAudioSource(int channels,
                                         double freq, double sample_freq)
    : channels_(channels),
      f_(freq / sample_freq),
      time_state_(0),
      cap_(0),
      callbacks_(0),
      errors_(0) {
}

SineWaveAudioSource::~SineWaveAudioSource() {
}

// The implementation could be more efficient if a lookup table is constructed
// but it is efficient enough for our simple needs.
int SineWaveAudioSource::OnMoreData(base::TimeDelta /* delay */,
                                    base::TimeTicks /* delay_timestamp */,
                                    int /* prior_frames_skipped */,
                                    AudioBus* dest) {
  base::AutoLock auto_lock(time_lock_);
  callbacks_++;

  // The table is filled with s(t) = kint16max*sin(Theta*t),
  // where Theta = 2*PI*fs.
  // We store the discrete time value |t| in a member to ensure that the
  // next pass starts at a correct state.
  int max_frames =
      cap_ > 0 ? std::min(dest->frames(), cap_ - time_state_) : dest->frames();
  for (int i = 0; i < max_frames; ++i)
    dest->channel(0)[i] = sin(2.0 * M_PI * f_ * time_state_++);
  for (int i = 1; i < dest->channels(); ++i) {
    memcpy(dest->channel(i), dest->channel(0),
           max_frames * sizeof(*dest->channel(i)));
  }
  return max_frames;
}

void SineWaveAudioSource::OnError(AudioOutputStream* stream) {
  errors_++;
}

void SineWaveAudioSource::CapSamples(int cap) {
  base::AutoLock auto_lock(time_lock_);
  DCHECK_GT(cap, 0);
  cap_ = cap;
}

void SineWaveAudioSource::Reset() {
  base::AutoLock auto_lock(time_lock_);
  time_state_ = 0;
}

FileSource::FileSource(const AudioParameters& params,
                       const base::FilePath& path_to_wav_file,
                       bool loop)
    : params_(params),
      path_to_wav_file_(path_to_wav_file),
      wav_file_read_pos_(0),
      load_failed_(false),
      looping_(loop) {}

FileSource::~FileSource() {
}

void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) {
  // Don't try again if we already failed.
  if (load_failed_)
    return;

  // Read the file, and put its data in a scoped_ptr so it gets deleted when
  // this class destructs. This data must be valid for the lifetime of
  // |wav_audio_handler_|.
  size_t length = 0u;
  raw_wav_data_ = ReadWavFile(path_to_wav_file, &length);
  if (!raw_wav_data_) {
    load_failed_ = true;
    return;
  }

  // Attempt to create a handler with this data. If the data is invalid, return.
  wav_audio_handler_ =
      WavAudioHandler::Create(base::StringPiece(raw_wav_data_.get(), length));
  if (!wav_audio_handler_) {
    LOG(ERROR) << "WAV data could be read but is not valid";
    load_failed_ = true;
    return;
  }

  // Hook us up so we pull in data from the file into the converter. We need to
  // modify the wav file's audio parameters since we'll be reading small slices
  // of it at a time and not the whole thing (like 10 ms at a time).
  AudioParameters file_audio_slice(
      AudioParameters::AUDIO_PCM_LOW_LATENCY,
      GuessChannelLayout(wav_audio_handler_->num_channels()),
      wav_audio_handler_->sample_rate(), wav_audio_handler_->bits_per_sample(),
      params_.frames_per_buffer());

  file_audio_converter_.reset(
      new AudioConverter(file_audio_slice, params_, false));
  file_audio_converter_->AddInput(this);
}

int FileSource::OnMoreData(base::TimeDelta /* delay */,
                           base::TimeTicks /* delay_timestamp */,
                           int /* prior_frames_skipped */,
                           AudioBus* dest) {
  // Load the file if we haven't already. This load needs to happen on the
  // audio thread, otherwise we'll run on the UI thread on Mac for instance.
  // This will massively delay the first OnMoreData, but we'll catch up.
  if (!wav_audio_handler_)
    LoadWavFile(path_to_wav_file_);
  if (load_failed_)
    return 0;

  DCHECK(wav_audio_handler_.get());

  if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) {
    if (looping_)
      Rewind();
    else
      return 0;
  }

  // This pulls data from ProvideInput.
  file_audio_converter_->Convert(dest);
  return dest->frames();
}

void FileSource::Rewind() {
  wav_file_read_pos_ = 0;
}

double FileSource::ProvideInput(AudioBus* audio_bus_into_converter,
                                uint32_t frames_delayed) {
  // Unfilled frames will be zeroed by CopyTo.
  size_t bytes_written;
  wav_audio_handler_->CopyTo(audio_bus_into_converter, wav_file_read_pos_,
                             &bytes_written);
  wav_file_read_pos_ += bytes_written;
  return 1.0;
}

void FileSource::OnError(AudioOutputStream* stream) {
}

BeepingSource::BeepingSource(const AudioParameters& params)
    : buffer_size_(params.GetBytesPerBuffer()),
      buffer_(new uint8_t[buffer_size_]),
      params_(params),
      last_callback_time_(base::TimeTicks::Now()),
      beep_duration_in_buffers_(kBeepDurationMilliseconds *
                                params.sample_rate() /
                                params.frames_per_buffer() /
                                1000),
      beep_generated_in_buffers_(0),
      beep_period_in_frames_(params.sample_rate() / kBeepFrequency) {}

BeepingSource::~BeepingSource() {
}

int BeepingSource::OnMoreData(base::TimeDelta /* delay */,
                              base::TimeTicks /* delay_timestamp */,
                              int /* prior_frames_skipped */,
                              AudioBus* dest) {
  // Accumulate the time from the last beep.
  interval_from_last_beep_ += base::TimeTicks::Now() - last_callback_time_;

  memset(buffer_.get(), 0, buffer_size_);
  bool should_beep = false;
  BeepContext* beep_context = GetBeepContext();
  if (beep_context->automatic_beep()) {
    base::TimeDelta delta = interval_from_last_beep_ -
        base::TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs);
    if (delta > base::TimeDelta()) {
      should_beep = true;
      interval_from_last_beep_ = delta;
    }
  } else {
    should_beep = beep_context->beep_once();
    beep_context->SetBeepOnce(false);
  }

  // If this object was instructed to generate a beep or has started to
  // generate a beep sound.
  if (should_beep || beep_generated_in_buffers_) {
    // Compute the number of frames to output high value. Then compute the
    // number of bytes based on channels and bits per channel.
    int high_frames = beep_period_in_frames_ / 2;
    int high_bytes = high_frames * params_.bits_per_sample() *
        params_.channels() / 8;

    // Separate high and low with the same number of bytes to generate a
    // square wave.
    int position = 0;
    while (position + high_bytes <= buffer_size_) {
      // Write high values first.
      memset(buffer_.get() + position, 128, high_bytes);
      // Then leave low values in the buffer with |high_bytes|.
      position += high_bytes * 2;
    }

    ++beep_generated_in_buffers_;
    if (beep_generated_in_buffers_ >= beep_duration_in_buffers_)
      beep_generated_in_buffers_ = 0;
  }

  last_callback_time_ = base::TimeTicks::Now();
  dest->FromInterleaved(buffer_.get(), dest->frames(),
                        params_.bits_per_sample() / 8);
  return dest->frames();
}

void BeepingSource::OnError(AudioOutputStream* stream) {
}

void BeepingSource::BeepOnce() {
  GetBeepContext()->SetBeepOnce(true);
}

}  // namespace media
