// Copyright 2016 The Fuchsia 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 "src/media/playback/mediaplayer/ffmpeg/lpcm_util.h"

#include "src/lib/fxl/logging.h"
#include "src/media/playback/mediaplayer/graph/formatting.h"

namespace media_player {

// LpcmUtil implementation that processes samples of type T.
template <typename T>
class LpcmUtilImpl : public LpcmUtil {
 public:
  ~LpcmUtilImpl();

  void Silence(void* buffer, size_t frame_count) const override;

  void Copy(const void* in, void* out, size_t frame_count) const override;

  void Mix(const void* in, void* out, size_t frame_count) const override;

  void Interleave(const void* in, size_t in_byte_count, void* out,
                  size_t frame_count) const override;

 private:
  LpcmUtilImpl(const AudioStreamType& stream_type);

  AudioStreamType stream_type_;

  friend class LpcmUtil;
};

std::unique_ptr<LpcmUtil> LpcmUtil::Create(const AudioStreamType& stream_type) {
  LpcmUtil* result;
  switch (stream_type.sample_format()) {
    case AudioStreamType::SampleFormat::kUnsigned8:
      result = new LpcmUtilImpl<uint8_t>(stream_type);
      break;
    case AudioStreamType::SampleFormat::kSigned16:
      result = new LpcmUtilImpl<int16_t>(stream_type);
      break;
    case AudioStreamType::SampleFormat::kSigned24In32:
      result = new LpcmUtilImpl<int32_t>(stream_type);
      break;
    case AudioStreamType::SampleFormat::kFloat:
      result = new LpcmUtilImpl<float>(stream_type);
      break;
    default:
      FXL_DCHECK(false) << "unsupported sample format "
                        << stream_type.sample_format();
      result = nullptr;
      break;
  }

  return std::unique_ptr<LpcmUtil>(result);
}

template <typename T>
LpcmUtilImpl<T>::LpcmUtilImpl(const AudioStreamType& stream_type)
    : stream_type_(stream_type) {}

template <typename T>
LpcmUtilImpl<T>::~LpcmUtilImpl() {}

template <typename T>
void LpcmUtilImpl<T>::Silence(void* buffer, size_t frame_count) const {
  T* sample = reinterpret_cast<T*>(buffer);
  for (size_t sample_countdown = frame_count * stream_type_.channels();
       sample_countdown != 0; --sample_countdown) {
    *sample = 0;
    sample++;
  }
}

template <>
void LpcmUtilImpl<uint8_t>::Silence(void* buffer, size_t frame_count) const {
  std::memset(buffer, 0x80, frame_count * stream_type_.bytes_per_frame());
}

template <>
void LpcmUtilImpl<int16_t>::Silence(void* buffer, size_t frame_count) const {
  std::memset(buffer, 0, frame_count * stream_type_.bytes_per_frame());
}

template <>
void LpcmUtilImpl<int32_t>::Silence(void* buffer, size_t frame_count) const {
  std::memset(buffer, 0, frame_count * stream_type_.bytes_per_frame());
}

template <typename T>
void LpcmUtilImpl<T>::Copy(const void* in, void* out,
                           size_t frame_count) const {
  std::memcpy(out, in, stream_type_.min_buffer_size(frame_count));
}

template <typename T>
void LpcmUtilImpl<T>::Mix(const void* in, void* out, size_t frame_count) const {
  const T* in_sample = reinterpret_cast<const T*>(in);
  T* out_sample = reinterpret_cast<T*>(out);
  for (size_t sample_countdown = frame_count * stream_type_.channels();
       sample_countdown != 0; --sample_countdown) {
    *out_sample += *in_sample;  // TODO(dalesat): Limit.
    out_sample++;
    in_sample++;
  }
}

template <>
void LpcmUtilImpl<uint8_t>::Mix(const void* in, void* out,
                                size_t frame_count) const {
  const uint8_t* in_sample = reinterpret_cast<const uint8_t*>(in);
  uint8_t* out_sample = reinterpret_cast<uint8_t*>(out);
  for (size_t sample_countdown = frame_count * stream_type_.channels();
       sample_countdown != 0; --sample_countdown) {
    *out_sample = uint8_t(uint16_t(*out_sample) + uint16_t(*in_sample) - 0x80);
    // TODO(dalesat): Limit.
    out_sample++;
    in_sample++;
  }
}

template <typename T>
void LpcmUtilImpl<T>::Interleave(const void* in, size_t in_byte_count,
                                 void* out, size_t frame_count) const {
  FXL_DCHECK(in);
  FXL_DCHECK(in_byte_count);
  FXL_DCHECK(out);
  FXL_DCHECK(frame_count);

  uint32_t channels = stream_type_.channels();
  FXL_DCHECK(channels);
  FXL_DCHECK(stream_type_.bytes_per_frame() != 0);
  FXL_DCHECK(in_byte_count % stream_type_.bytes_per_frame() == 0);
  FXL_DCHECK(in_byte_count >= frame_count * stream_type_.bytes_per_frame());
  uint64_t in_channel_stride = in_byte_count / stream_type_.bytes_per_frame();

  const T* in_channel = reinterpret_cast<const T*>(in);
  T* out_channel = reinterpret_cast<T*>(out);

  for (uint32_t channel = channels; channel != 0; --channel) {
    const T* in_sample = in_channel;
    T* out_sample = out_channel;
    for (uint64_t frame = frame_count; frame != 0; --frame) {
      *out_sample = *in_sample;
      ++in_sample;
      out_sample += channels;
    }
    in_channel += in_channel_stride;
    ++out_channel;
  }
}

}  // namespace media_player
