/*
 *  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 "webrtc/common_audio/audio_converter.h"

#include <cstring>

#include "webrtc/base/checks.h"
#include "webrtc/base/safe_conversions.h"
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/common_audio/resampler/push_sinc_resampler.h"
#include "webrtc/system_wrappers/interface/scoped_vector.h"

using rtc::checked_cast;

namespace webrtc {

class CopyConverter : public AudioConverter {
 public:
  CopyConverter(int src_channels, size_t src_frames, int 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 (int i = 0; i < src_channels(); ++i)
        std::memcpy(dst[i], src[i], dst_frames() * sizeof(*dst[i]));
    }
  }
};

class UpmixConverter : public AudioConverter {
 public:
  UpmixConverter(int src_channels, size_t src_frames, int 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 (int j = 0; j < dst_channels(); ++j)
        dst[j][i] = value;
    }
  }
};

class DownmixConverter : public AudioConverter {
 public:
  DownmixConverter(int src_channels, size_t src_frames, int 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 (int j = 0; j < src_channels(); ++j)
        sum += src[j][i];
      dst_mono[i] = sum / src_channels();
    }
  }
};

class ResampleConverter : public AudioConverter {
 public:
  ResampleConverter(int src_channels, size_t src_frames, int dst_channels,
                    size_t dst_frames)
      : AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {
    resamplers_.reserve(src_channels);
    for (int i = 0; i < src_channels; ++i)
      resamplers_.push_back(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:
  ScopedVector<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:
  CompositionConverter(ScopedVector<AudioConverter> converters)
      : converters_(converters.Pass()) {
    RTC_CHECK_GE(converters_.size(), 2u);
    // We need an intermediate buffer after every converter.
    for (auto it = converters_.begin(); it != converters_.end() - 1; ++it)
      buffers_.push_back(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:
  ScopedVector<AudioConverter> converters_;
  ScopedVector<ChannelBuffer<float>> buffers_;
};

rtc::scoped_ptr<AudioConverter> AudioConverter::Create(int src_channels,
                                                       size_t src_frames,
                                                       int dst_channels,
                                                       size_t dst_frames) {
  rtc::scoped_ptr<AudioConverter> sp;
  if (src_channels > dst_channels) {
    if (src_frames != dst_frames) {
      ScopedVector<AudioConverter> converters;
      converters.push_back(new DownmixConverter(src_channels, src_frames,
                                                dst_channels, src_frames));
      converters.push_back(new ResampleConverter(dst_channels, src_frames,
                                                 dst_channels, dst_frames));
      sp.reset(new CompositionConverter(converters.Pass()));
    } else {
      sp.reset(new DownmixConverter(src_channels, src_frames, dst_channels,
                                    dst_frames));
    }
  } else if (src_channels < dst_channels) {
    if (src_frames != dst_frames) {
      ScopedVector<AudioConverter> converters;
      converters.push_back(new ResampleConverter(src_channels, src_frames,
                                                 src_channels, dst_frames));
      converters.push_back(new UpmixConverter(src_channels, dst_frames,
                                              dst_channels, dst_frames));
      sp.reset(new CompositionConverter(converters.Pass()));
    } 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.Pass();
}

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

AudioConverter::AudioConverter(int src_channels, size_t src_frames,
                               int 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
