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

#include "common_audio/audio_converter.h"

#include <cstring>
#include <memory>
#include <utility>
#include <vector>

#include "common_audio/channel_buffer.h"
#include "common_audio/resampler/push_sinc_resampler.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"

namespace webrtc {

class CopyConverter : public AudioConverter {
 public:
  CopyConverter(size_t src_channels,
                size_t src_frames,
                size_t dst_channels,
                size_t dst_frames)
      : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {}
  ~CopyConverter() override {}

  void Convert(const float* const* src,
               size_t src_size,
               float* const* dst,
               size_t dst_capacity) override {
    CheckSizes(src_size, dst_capacity);
    if (src != dst) {
      for (size_t i = 0; i < src_channels(); ++i)
        std::memcpy(dst[i], src[i], dst_frames() * sizeof(*dst[i]));
    }
  }
};

class UpmixConverter : public AudioConverter {
 public:
  UpmixConverter(size_t src_channels,
                 size_t src_frames,
                 size_t dst_channels,
                 size_t dst_frames)
      : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {}
  ~UpmixConverter() override {}

  void Convert(const float* const* src,
               size_t src_size,
               float* const* dst,
               size_t dst_capacity) override {
    CheckSizes(src_size, dst_capacity);
    for (size_t i = 0; i < dst_frames(); ++i) {
      const float value = src[0][i];
      for (size_t j = 0; j < dst_channels(); ++j)
        dst[j][i] = value;
    }
  }
};

class DownmixConverter : public AudioConverter {
 public:
  DownmixConverter(size_t src_channels,
                   size_t src_frames,
                   size_t dst_channels,
                   size_t dst_frames)
      : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {}
  ~DownmixConverter() override {}

  void Convert(const float* const* src,
               size_t src_size,
               float* const* dst,
               size_t dst_capacity) override {
    CheckSizes(src_size, dst_capacity);
    float* dst_mono = dst[0];
    for (size_t i = 0; i < src_frames(); ++i) {
      float sum = 0;
      for (size_t j = 0; j < src_channels(); ++j)
        sum += src[j][i];
      dst_mono[i] = sum / src_channels();
    }
  }
};

class ResampleConverter : public AudioConverter {
 public:
  ResampleConverter(size_t src_channels,
                    size_t src_frames,
                    size_t dst_channels,
                    size_t dst_frames)
      : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {
    resamplers_.reserve(src_channels);
    for (size_t i = 0; i < src_channels; ++i)
      resamplers_.push_back(std::unique_ptr<PushSincResampler>(
          new PushSincResampler(src_frames, dst_frames)));
  }
  ~ResampleConverter() override {}

  void Convert(const float* const* src,
               size_t src_size,
               float* const* dst,
               size_t dst_capacity) override {
    CheckSizes(src_size, dst_capacity);
    for (size_t i = 0; i < resamplers_.size(); ++i)
      resamplers_[i]->Resample(src[i], src_frames(), dst[i], dst_frames());
  }

 private:
  std::vector<std::unique_ptr<PushSincResampler>> resamplers_;
};

// Apply a vector of converters in serial, in the order given. At least two
// converters must be provided.
class CompositionConverter : public AudioConverter {
 public:
  explicit CompositionConverter(
      std::vector<std::unique_ptr<AudioConverter>> converters)
      : converters_(std::move(converters)) {
    RTC_CHECK_GE(converters_.size(), 2);
    // We need an intermediate buffer after every converter.
    for (auto it = converters_.begin(); it != converters_.end() - 1; ++it)
      buffers_.push_back(
          std::unique_ptr<ChannelBuffer<float>>(new ChannelBuffer<float>(
              (*it)->dst_frames(), (*it)->dst_channels())));
  }
  ~CompositionConverter() override {}

  void Convert(const float* const* src,
               size_t src_size,
               float* const* dst,
               size_t dst_capacity) override {
    converters_.front()->Convert(src, src_size, buffers_.front()->channels(),
                                 buffers_.front()->size());
    for (size_t i = 2; i < converters_.size(); ++i) {
      auto& src_buffer = buffers_[i - 2];
      auto& dst_buffer = buffers_[i - 1];
      converters_[i]->Convert(src_buffer->channels(), src_buffer->size(),
                              dst_buffer->channels(), dst_buffer->size());
    }
    converters_.back()->Convert(buffers_.back()->channels(),
                                buffers_.back()->size(), dst, dst_capacity);
  }

 private:
  std::vector<std::unique_ptr<AudioConverter>> converters_;
  std::vector<std::unique_ptr<ChannelBuffer<float>>> buffers_;
};

std::unique_ptr<AudioConverter> AudioConverter::Create(size_t src_channels,
                                                       size_t src_frames,
                                                       size_t dst_channels,
                                                       size_t dst_frames) {
  std::unique_ptr<AudioConverter> sp;
  if (src_channels > dst_channels) {
    if (src_frames != dst_frames) {
      std::vector<std::unique_ptr<AudioConverter>> converters;
      converters.push_back(std::unique_ptr<AudioConverter>(new DownmixConverter(
          src_channels, src_frames, dst_channels, src_frames)));
      converters.push_back(
          std::unique_ptr<AudioConverter>(new ResampleConverter(
              dst_channels, src_frames, dst_channels, dst_frames)));
      sp.reset(new CompositionConverter(std::move(converters)));
    } else {
      sp.reset(new DownmixConverter(src_channels, src_frames, dst_channels,
                                    dst_frames));
    }
  } else if (src_channels < dst_channels) {
    if (src_frames != dst_frames) {
      std::vector<std::unique_ptr<AudioConverter>> converters;
      converters.push_back(
          std::unique_ptr<AudioConverter>(new ResampleConverter(
              src_channels, src_frames, src_channels, dst_frames)));
      converters.push_back(std::unique_ptr<AudioConverter>(new UpmixConverter(
          src_channels, dst_frames, dst_channels, dst_frames)));
      sp.reset(new CompositionConverter(std::move(converters)));
    } else {
      sp.reset(new UpmixConverter(src_channels, src_frames, dst_channels,
                                  dst_frames));
    }
  } else if (src_frames != dst_frames) {
    sp.reset(new ResampleConverter(src_channels, src_frames, dst_channels,
                                   dst_frames));
  } else {
    sp.reset(
        new CopyConverter(src_channels, src_frames, dst_channels, dst_frames));
  }

  return sp;
}

// For CompositionConverter.
AudioConverter::AudioConverter()
    : src_channels_(0), src_frames_(0), dst_channels_(0), dst_frames_(0) {}

AudioConverter::AudioConverter(size_t src_channels,
                               size_t src_frames,
                               size_t dst_channels,
                               size_t dst_frames)
    : src_channels_(src_channels),
      src_frames_(src_frames),
      dst_channels_(dst_channels),
      dst_frames_(dst_frames) {
  RTC_CHECK(dst_channels == src_channels || dst_channels == 1 ||
            src_channels == 1);
}

void AudioConverter::CheckSizes(size_t src_size, size_t dst_capacity) const {
  RTC_CHECK_EQ(src_size, src_channels() * src_frames());
  RTC_CHECK_GE(dst_capacity, dst_channels() * dst_frames());
}

}  // namespace webrtc
