// 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.

#include "media/audio/simple_sources.h"

#include <stddef.h>

#include <algorithm>
#include <memory>

#include "base/files/file.h"
#include "base/logging.h"
#include "base/numerics/math_constants.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/audio/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."
                  " Try disabling the sandbox with --no-sandbox.";
    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_ GUARDED_BY(lock_);
  bool automatic_beep_ GUARDED_BY(lock_);
};

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) {}

SineWaveAudioSource::~SineWaveAudioSource() = default;

// 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) {
  int max_frames;

  {
    base::AutoLock auto_lock(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.
    max_frames = cap_ > 0 ? std::min(dest->frames(), cap_ - pos_samples_)
                          : dest->frames();
    for (int i = 0; i < max_frames; ++i)
      dest->channel(0)[i] = sin(2.0 * base::kPiDouble * f_ * pos_samples_++);
    for (int i = 1; i < dest->channels(); ++i) {
      memcpy(dest->channel(i), dest->channel(0),
             max_frames * sizeof(*dest->channel(i)));
    }
  }

  if (on_more_data_callback_)
    on_more_data_callback_.Run();

  return max_frames;
}

void SineWaveAudioSource::OnError(ErrorType type) {
  errors_++;
}

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

void SineWaveAudioSource::Reset() {
  base::AutoLock auto_lock(lock_);
  pos_samples_ = 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() = default;

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(), params_.frames_per_buffer());

  file_audio_converter_ =
      std::make_unique<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(ErrorType type) {}

BeepingSource::BeepingSource(const AudioParameters& params)
    : buffer_size_(params.GetBytesPerBuffer(kSampleFormatU8)),
      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() = default;

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(), 128, buffer_size_);
  bool should_beep = false;
  BeepContext* beep_context = GetBeepContext();
  if (beep_context->automatic_beep()) {
    base::TimeDelta delta = interval_from_last_beep_ -
                            base::Milliseconds(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.
    int high_frames = beep_period_in_frames_ / 2;
    int high_bytes = high_frames * params_.channels();

    // 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, 255, 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<UnsignedInt8SampleTypeTraits>(buffer_.get(),
                                                      dest->frames());
  return dest->frames();
}

void BeepingSource::OnError(ErrorType type) {}

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

}  // namespace media
