/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cobalt/audio/audio_device.h"

#include "base/debug/trace_event.h"
#include "base/memory/scoped_ptr.h"
#include "cobalt/audio/audio_helpers.h"
#if defined(OS_STARBOARD)
#include "starboard/audio_sink.h"
#include "starboard/configuration.h"
#endif  // defined(OS_STARBOARD)
#include "media/audio/audio_parameters.h"
#include "media/audio/shell_audio_streamer.h"
#include "media/base/audio_bus.h"

namespace cobalt {
namespace audio {

using ::media::AudioBus;
using ::media::ShellAudioBus;

namespace {
const int kRenderBufferSizeFrames = 1024;
const int kFramesPerChannel = kRenderBufferSizeFrames * 4;
const int kStandardOutputSampleRate = 48000;
}  // namespace

#if defined(OS_STARBOARD)
#if SB_CAN(MEDIA_USE_STARBOARD_PIPELINE)
#define SB_USE_SB_AUDIO_SINK 1
#endif  // SB_CAN(MEDIA_USE_STARBOARD_PIPELINE)
#endif  // defined(OS_STARBOARD)

#if defined(SB_USE_SB_AUDIO_SINK)

class AudioDevice::Impl {
 public:
  Impl(int number_of_channels, RenderCallback* callback);
  ~Impl();

 private:
  static void UpdateSourceStatusFunc(int* frames_in_buffer,
                                     int* offset_in_frames, bool* is_playing,
                                     bool* is_eos_reached, void* context);
  static void ConsumeFramesFunc(int frames_consumed, void* context);

  void UpdateSourceStatus(int* frames_in_buffer, int* offset_in_frames,
                          bool* is_playing, bool* is_eos_reached);
  void ConsumeFrames(int frames_consumed);

  void FillOutputAudioBus();

  template <typename InputType, typename OutputType>
  inline void FillOutputAudioBusForType();

  int number_of_channels_;
  SbMediaAudioSampleType output_sample_type_;
  RenderCallback* render_callback_;

  // The |render_callback_| returns audio data in planar form.  So we read it
  // into |input_audio_bus_| and convert it into interleaved form and store in
  // |output_frame_buffer_|.
  ShellAudioBus input_audio_bus_;

  scoped_array<uint8> output_frame_buffer_;

  void* frame_buffers_[1];
  int64 frames_rendered_;  // Frames retrieved from |render_callback_|.
  int64 frames_consumed_;  // Accumulated frames consumed reported by the sink.

  bool was_silence_last_update_;

  SbAudioSink audio_sink_;

  DISALLOW_COPY_AND_ASSIGN(Impl);
};

// AudioDevice::Impl.
AudioDevice::Impl::Impl(int number_of_channels, RenderCallback* callback)
    : number_of_channels_(number_of_channels),
      output_sample_type_(GetPreferredOutputStarboardSampleType()),
      render_callback_(callback),
      input_audio_bus_(static_cast<size_t>(number_of_channels),
                       static_cast<size_t>(kRenderBufferSizeFrames),
                       GetPreferredOutputSampleType(), ShellAudioBus::kPlanar),
      output_frame_buffer_(
          new uint8[kFramesPerChannel * number_of_channels_ *
                    GetStarboardSampleTypeSize(output_sample_type_)]),
      frames_rendered_(0),
      frames_consumed_(0),
      was_silence_last_update_(false),
      audio_sink_(kSbAudioSinkInvalid) {
  DCHECK(number_of_channels_ == 1 || number_of_channels_ == 2)
      << "Invalid number of channels: " << number_of_channels_;
  DCHECK(render_callback_);
  DCHECK(SbAudioSinkIsAudioFrameStorageTypeSupported(
      kSbMediaAudioFrameStorageTypeInterleaved))
      << "Only interleaved frame storage is supported.";
  DCHECK(SbAudioSinkIsAudioSampleTypeSupported(output_sample_type_))
      << "Output sample type " << output_sample_type_ << " is not supported.";

  frame_buffers_[0] = output_frame_buffer_.get();
  audio_sink_ = SbAudioSinkCreate(
      number_of_channels_, kStandardOutputSampleRate, output_sample_type_,
      kSbMediaAudioFrameStorageTypeInterleaved, frame_buffers_,
      kFramesPerChannel, &AudioDevice::Impl::UpdateSourceStatusFunc,
      &AudioDevice::Impl::ConsumeFramesFunc, this);
  DCHECK(SbAudioSinkIsValid(audio_sink_));
}

AudioDevice::Impl::~Impl() {
  if (SbAudioSinkIsValid(audio_sink_)) {
    SbAudioSinkDestroy(audio_sink_);
  }
}

// static
void AudioDevice::Impl::UpdateSourceStatusFunc(int* frames_in_buffer,
                                               int* offset_in_frames,
                                               bool* is_playing,
                                               bool* is_eos_reached,
                                               void* context) {
  AudioDevice::Impl* impl = reinterpret_cast<AudioDevice::Impl*>(context);
  DCHECK(impl);
  DCHECK(frames_in_buffer);
  DCHECK(offset_in_frames);
  DCHECK(is_playing);
  DCHECK(is_eos_reached);

  impl->UpdateSourceStatus(frames_in_buffer, offset_in_frames, is_playing,
                           is_eos_reached);
}

// static
void AudioDevice::Impl::ConsumeFramesFunc(int frames_consumed, void* context) {
  AudioDevice::Impl* impl = reinterpret_cast<AudioDevice::Impl*>(context);
  DCHECK(impl);

  impl->ConsumeFrames(frames_consumed);
}

void AudioDevice::Impl::UpdateSourceStatus(int* frames_in_buffer,
                                           int* offset_in_frames,
                                           bool* is_playing,
                                           bool* is_eos_reached) {
  TRACE_EVENT0("cobalt::audio", "AudioDevice::Impl::UpdateSourceStatus()");
  *is_playing = true;
  *is_eos_reached = false;

  // Assert that we never consume more than we've rendered.
  DCHECK_GE(frames_rendered_, frames_consumed_);
  *frames_in_buffer = static_cast<int>(frames_rendered_ - frames_consumed_);

  if ((kFramesPerChannel - *frames_in_buffer) >= kRenderBufferSizeFrames) {
    bool silence = false;

    // If there was silence last time we were called, then the buffer has
    // already been zeroed out and we don't need to do it again.
    if (!was_silence_last_update_) {
      input_audio_bus_.ZeroAllFrames();
    }

    // Fill our temporary buffer with planar PCM float samples.
    render_callback_->FillAudioBus(&input_audio_bus_, &silence);

    if (!silence) {
      FillOutputAudioBus();

      frames_rendered_ += kRenderBufferSizeFrames;
      *frames_in_buffer += kRenderBufferSizeFrames;
    }

    was_silence_last_update_ = silence;
  }

  *offset_in_frames = frames_consumed_ % kFramesPerChannel;
  *is_playing = (frames_rendered_ != frames_consumed_);
}

void AudioDevice::Impl::ConsumeFrames(int frames_consumed) {
  frames_consumed_ += frames_consumed;
}

template <typename InputType, typename OutputType>
inline void AudioDevice::Impl::FillOutputAudioBusForType() {
  // Determine the offset into the audio bus that represents the tail of
  // buffered data.
  uint64 channel_offset = frames_rendered_ % kFramesPerChannel;

  OutputType* output_buffer =
      reinterpret_cast<OutputType*>(output_frame_buffer_.get());
  output_buffer += channel_offset * number_of_channels_;
  for (size_t frame = 0; frame < kRenderBufferSizeFrames; ++frame) {
    for (size_t channel = 0; channel < input_audio_bus_.channels(); ++channel) {
      *output_buffer = ConvertSample<InputType, OutputType>(
          input_audio_bus_
              .GetSampleForType<InputType, media::ShellAudioBus::kPlanar>(
                  channel, frame));
      ++output_buffer;
    }
  }
}

void AudioDevice::Impl::FillOutputAudioBus() {
  TRACE_EVENT0("cobalt::audio", "AudioDevice::Impl::FillOutputAudioBus()");

  const bool is_input_int16 =
      input_audio_bus_.sample_type() == media::ShellAudioBus::kInt16;
  const bool is_output_int16 =
      output_sample_type_ == kSbMediaAudioSampleTypeInt16;

  if (is_input_int16 && is_output_int16) {
    FillOutputAudioBusForType<int16, int16>();
  } else if (!is_input_int16 && is_output_int16) {
    FillOutputAudioBusForType<float, int16>();
  } else if (is_input_int16 && !is_output_int16) {
    FillOutputAudioBusForType<int16, float>();
  } else if (!is_input_int16 && !is_output_int16) {
    FillOutputAudioBusForType<float, float>();
  } else {
    NOTREACHED();
  }
}

#else  // defined(SB_USE_SB_AUDIO_SINK)

class AudioDevice::Impl : public ::media::ShellAudioStream {
 public:
  typedef ::media::AudioBus AudioBus;
  typedef ::media::AudioParameters AudioParameters;

  Impl(int32 number_of_channels, RenderCallback* callback);
  virtual ~Impl();

  // ShellAudioStream implementation.
  bool PauseRequested() const OVERRIDE;
  bool PullFrames(uint32* offset_in_frame, uint32* total_frames) OVERRIDE;
  void ConsumeFrames(uint32 frame_played) OVERRIDE;
  const AudioParameters& GetAudioParameters() const OVERRIDE;
  AudioBus* GetAudioBus() OVERRIDE;

 private:
  typedef ::media::ShellAudioBus ShellAudioBus;

  int GetAudioHardwareSampleRate();

  void FillOutputAudioBus();

  AudioParameters audio_parameters_;
  scoped_ptr<AudioBus> output_audio_bus_;

  uint64 rendered_frame_cursor_;
  uint64 buffered_frame_cursor_;
  bool needs_data_;

  // Buffer the audio data which is pulled from upper level.
  ShellAudioBus audio_bus_;

  RenderCallback* render_callback_;

  DISALLOW_COPY_AND_ASSIGN(Impl);
};

// AudioDevice::Impl.
AudioDevice::Impl::Impl(int32 number_of_channels, RenderCallback* callback)
    : rendered_frame_cursor_(0),
      buffered_frame_cursor_(0),
      needs_data_(true),
      audio_bus_(static_cast<size_t>(number_of_channels),
                 static_cast<size_t>(kRenderBufferSizeFrames),
                 ShellAudioBus::kFloat32, ShellAudioBus::kPlanar),
      render_callback_(callback) {
  TRACE_EVENT0("cobalt::audio", "AudioDevice::Impl::Impl()");

  DCHECK_GT(number_of_channels, 0);
  DCHECK(media::ShellAudioStreamer::Instance()->GetConfig().interleaved())
      << "Planar audio is not supported.";

  int bytes_per_sample = static_cast<int>(
      media::ShellAudioStreamer::Instance()->GetConfig().bytes_per_sample());

  DCHECK_EQ(bytes_per_sample, sizeof(float))
      << bytes_per_sample << " bytes per sample is not supported.";

  media::ChannelLayout channel_layout = number_of_channels == 1
                                            ? media::CHANNEL_LAYOUT_MONO
                                            : media::CHANNEL_LAYOUT_STEREO;

  audio_parameters_ =
      media::AudioParameters(media::AudioParameters::AUDIO_PCM_LINEAR,
                             channel_layout, GetAudioHardwareSampleRate(),
                             bytes_per_sample * 8, kRenderBufferSizeFrames);

  // Create 1 channel audio bus since we only support interleaved.
  output_audio_bus_ =
      AudioBus::Create(1, kFramesPerChannel * number_of_channels);

  audio_bus_.ZeroAllFrames();

  media::ShellAudioStreamer::Instance()->AddStream(this);
}

AudioDevice::Impl::~Impl() {
  media::ShellAudioStreamer::Instance()->RemoveStream(this);
}

bool AudioDevice::Impl::PauseRequested() const { return needs_data_; }

bool AudioDevice::Impl::PullFrames(uint32* offset_in_frame,
                                   uint32* total_frames) {
  TRACE_EVENT0("cobalt::audio", "AudioDevice::Impl::PullFrames()");

  // In case offset_in_frame or total_frames is NULL.
  uint32 dummy_offset_in_frame;
  uint32 dummy_total_frames;
  if (!offset_in_frame) {
    offset_in_frame = &dummy_offset_in_frame;
  }
  if (!total_frames) {
    total_frames = &dummy_total_frames;
  }

  // Assert that we never render more than has been buffered.
  DCHECK_GE(buffered_frame_cursor_, rendered_frame_cursor_);
  *total_frames =
      static_cast<uint32>(buffered_frame_cursor_ - rendered_frame_cursor_);

  if ((kFramesPerChannel - *total_frames) >= kRenderBufferSizeFrames) {
    // Fill our temporary buffer with PCM float samples.
    bool silence = false;
    render_callback_->FillAudioBus(&audio_bus_, &silence);

    if (!silence) {
      FillOutputAudioBus();

      buffered_frame_cursor_ += kRenderBufferSizeFrames;
      *total_frames += kRenderBufferSizeFrames;
    }
  }

  needs_data_ = *total_frames < kRenderBufferSizeFrames;
  *offset_in_frame = rendered_frame_cursor_ % kFramesPerChannel;
  return !PauseRequested();
}

void AudioDevice::Impl::ConsumeFrames(uint32 frame_played) {
  // Increment number of frames rendered by the hardware.
  rendered_frame_cursor_ += frame_played;
}

const AudioDevice::Impl::AudioParameters&
AudioDevice::Impl::GetAudioParameters() const {
  return audio_parameters_;
}

AudioDevice::Impl::AudioBus* AudioDevice::Impl::GetAudioBus() {
  return output_audio_bus_.get();
}

int AudioDevice::Impl::GetAudioHardwareSampleRate() {
  int native_output_sample_rate =
      static_cast<int>(media::ShellAudioStreamer::Instance()
                           ->GetConfig()
                           .native_output_sample_rate());
  if (native_output_sample_rate !=
      media::ShellAudioStreamer::Config::kInvalidSampleRate) {
    return native_output_sample_rate;
  }
  return kStandardOutputSampleRate;
}

void AudioDevice::Impl::FillOutputAudioBus() {
  TRACE_EVENT0("cobalt::audio", "AudioDevice::Impl::FillOutputAudioBus()");
  // Determine the offset into the audio bus that represents the tail of
  // buffered data.
  uint64 channel_offset = buffered_frame_cursor_ % kFramesPerChannel;

  float* output_buffer = output_audio_bus_->channel(0);
  output_buffer += channel_offset * audio_parameters_.channels();

  for (size_t i = 0; i < kRenderBufferSizeFrames; ++i) {
    for (size_t c = 0; c < audio_bus_.channels(); ++c) {
      *output_buffer = audio_bus_.GetFloat32Sample(c, i);
      ++output_buffer;
    }
  }

  // Clear the data in audio bus.
  audio_bus_.ZeroAllFrames();
}

#endif  // defined(SB_USE_SB_AUDIO_SINK)

// AudioDevice.
AudioDevice::AudioDevice(int32 number_of_channels, RenderCallback* callback)
    : impl_(new Impl(number_of_channels, callback)) {}

AudioDevice::~AudioDevice() {}

}  // namespace audio
}  // namespace cobalt
