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

// Modifications Copyright 2019 The Cobalt Authors. 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.
//
// Input buffer layout, dividing the total buffer into regions (r0_ - r5_):
//
// |----------------|-----------------------------------------|----------------|
//
//                                   kBlockSize + kKernelSize / 2
//                   <--------------------------------------------------------->
//                                              r0_
//
//  kKernelSize / 2   kKernelSize / 2         kKernelSize / 2   kKernelSize / 2
// <---------------> <--------------->       <---------------> <--------------->
//        r1_               r2_                     r3_               r4_
//
//                                                     kBlockSize
//                                     <--------------------------------------->
//                                                        r5_
//
// The algorithm:
//
// 1) Consume input frames into r0_ (r1_ is zero-initialized).
// 2) Position kernel centered at start of r0_ (r2_) and generate output frames
//    until kernel is centered at start of r4_ or we've finished generating all
//    the output frames.
// 3) Copy r3_ to r1_ and r4_ to r2_.
// 4) Consume input frames into r5_ (zero-pad if we run out of input).
// 5) Goto (2) until all of input is consumed.
//
// Note: we're glossing over how the sub-sample handling works with
// |virtual_source_idx_|, etc.

#include "cobalt/media/base/interleaved_sinc_resampler.h"

#include <algorithm>
#include <cmath>

#include "base/logging.h"
#include "starboard/memory.h"

namespace cobalt {
namespace media {

namespace {

// The kernel size can be adjusted for quality (higher is better) at the
// expense of performance.  Must be a multiple of 32.
const int kKernelSize = 32;

// The number of destination frames generated per processing pass.  Affects
// how often and for how much InterleavedSincResampler calls back for input.
// Must be greater than kKernelSize.
const int kBlockSize = 512;

// The kernel offset count is used for interpolation and is the number of
// sub-sample kernel shifts.  Can be adjusted for quality (higher is better)
// at the expense of allocating more memory.
const int kKernelOffsetCount = 32;
const int kKernelStorageSize = kKernelSize * (kKernelOffsetCount + 1);

// The size (in samples) of the internal buffer used by the resampler.
const int kBufferSize = kBlockSize + kKernelSize;

// The maximum numbers of buffer can be queued.
const int kMaximumPendingBuffers = 8;

}  // namespace

class InterleavedSincResampler::Buffer
    : public base::RefCountedThreadSafe<Buffer> {
 public:
  Buffer() : frames_(0) {}
  Buffer(const float* data, int frames, int channel_count) : frames_(frames) {
    data_.reset(new float[frames * channel_count]);
    memcpy(data_.get(), data, frames * channel_count * sizeof(float));
  }
  Buffer(std::unique_ptr<float[]> data, int frames)
      : data_(std::move(data)), frames_(frames) {}

  const float* GetData() const { return data_.get(); }

  int GetNumFrames() const { return frames_; }

  bool IsEndOfStream() const { return GetData() == NULL; }

 private:
  std::unique_ptr<float[]> data_;
  int frames_;

  DISALLOW_COPY_AND_ASSIGN(Buffer);
};

InterleavedSincResampler::InterleavedSincResampler(double io_sample_rate_ratio,
                                                   int channel_count)
    : io_sample_rate_ratio_(io_sample_rate_ratio),
      virtual_source_idx_(0),
      buffer_primed_(false),
      channel_count_(channel_count),
      frame_size_in_bytes_(sizeof(float) * channel_count_),
      // Create buffers with a 16-byte alignment for possible optimizations.
      kernel_storage_(static_cast<float*>(
          base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 16))),
      input_buffer_(static_cast<float*>(
          base::AlignedAlloc(frame_size_in_bytes_ * kBufferSize, 16))),
      offset_in_frames_(0),
      frames_resampled_(0),
      frames_queued_(0),
      // Setup various region pointers in the buffer (see diagram above).
      r0_(input_buffer_.get() + kKernelSize / 2 * channel_count_),
      r1_(input_buffer_.get()),
      r2_(r0_),
      r3_(r0_ + (kBlockSize - kKernelSize / 2) * channel_count_),
      r4_(r0_ + kBlockSize * channel_count_),
      r5_(r0_ + kKernelSize / 2 * channel_count_) {
  // Ensure kKernelSize is a multiple of 32 for easy SSE optimizations; causes
  // r0_ and r5_ (used for input) to always be 16-byte aligned by virtue of
  // input_buffer_ being 16-byte aligned.
  DCHECK_EQ(kKernelSize % 32, 0) << "kKernelSize must be a multiple of 32!";
  DCHECK_GT(kBlockSize, kKernelSize)
      << "kBlockSize must be greater than kKernelSize!";
  // Basic sanity checks to ensure buffer regions are laid out correctly:
  // r0_ and r2_ should always be the same position.
  DCHECK_EQ(r0_, r2_);
  // r1_ at the beginning of the buffer.
  DCHECK_EQ(r1_, input_buffer_.get());
  // r1_ left of r2_, r2_ left of r5_ and r1_, r2_ size correct.
  DCHECK_EQ(r2_ - r1_, r5_ - r2_);
  // r3_ left of r4_, r5_ left of r0_ and r3_ size correct.
  DCHECK_EQ(r4_ - r3_, r5_ - r0_);
  // r3_, r4_ size correct and r4_ at the end of the buffer.
  DCHECK_EQ(r4_ + (r4_ - r3_), r1_ + kBufferSize * channel_count_);
  // r5_ size correct and at the end of the buffer.
  DCHECK_EQ(r5_ + kBlockSize * channel_count_,
            r1_ + kBufferSize * channel_count_);

  memset(kernel_storage_.get(), 0,
              sizeof(*kernel_storage_.get()) * kKernelStorageSize);
  memset(input_buffer_.get(), 0, frame_size_in_bytes_ * kBufferSize);

  InitializeKernel();
}

InterleavedSincResampler::~InterleavedSincResampler() {}

void InterleavedSincResampler::InitializeKernel() {
  // Blackman window parameters.
  static const double kAlpha = 0.16;
  static const double kA0 = 0.5 * (1.0 - kAlpha);
  static const double kA1 = 0.5;
  static const double kA2 = 0.5 * kAlpha;

  // |sinc_scale_factor| is basically the normalized cutoff frequency of the
  // low-pass filter.
  double sinc_scale_factor =
      io_sample_rate_ratio_ > 1.0 ? 1.0 / io_sample_rate_ratio_ : 1.0;

  // The sinc function is an idealized brick-wall filter, but since we're
  // windowing it the transition from pass to stop does not happen right away.
  // So we should adjust the low pass filter cutoff slightly downward to avoid
  // some aliasing at the very high-end.
  // TODO: this value is empirical and to be more exact should vary depending
  // on kKernelSize.
  sinc_scale_factor *= 0.9;

  // Generates a set of windowed sinc() kernels.
  // We generate a range of sub-sample offsets from 0.0 to 1.0.
  for (int offset_idx = 0; offset_idx <= kKernelOffsetCount; ++offset_idx) {
    double subsample_offset =
        static_cast<double>(offset_idx) / kKernelOffsetCount;

    for (int i = 0; i < kKernelSize; ++i) {
      // Compute the sinc with offset.
      double s =
          sinc_scale_factor * M_PI * (i - kKernelSize / 2 - subsample_offset);
      double sinc = (!s ? 1.0 : sin(s) / s) * sinc_scale_factor;

      // Compute Blackman window, matching the offset of the sinc().
      double x = (i - subsample_offset) / kKernelSize;
      double window =
          kA0 - kA1 * cos(2.0 * M_PI * x) + kA2 * cos(4.0 * M_PI * x);

      // Window the sinc() function and store at the correct offset.
      kernel_storage_.get()[i + offset_idx * kKernelSize] = sinc * window;
    }
  }
}

void InterleavedSincResampler::QueueBuffer(const float* data, int frames) {
  DCHECK(CanQueueBuffer());

  if (!pending_buffers_.empty() && pending_buffers_.back()->IsEndOfStream()) {
    DCHECK(!data);
    return;
  }

  if (!data) {
    pending_buffers_.push(new Buffer);
    return;
  } else {
    frames_queued_ += frames;
    pending_buffers_.push(new Buffer(data, frames, channel_count_));
  }
}

void InterleavedSincResampler::QueueBuffer(std::unique_ptr<float[]> data,
                                           int frames) {
  DCHECK(CanQueueBuffer());

  if (!pending_buffers_.empty() && pending_buffers_.back()->IsEndOfStream()) {
    DCHECK(!data.get());
    return;
  }

  if (!data.get()) {
    pending_buffers_.push(new Buffer);
    return;
  } else {
    frames_queued_ += frames;
    pending_buffers_.push(new Buffer(std::move(data), frames));
  }
}

void InterleavedSincResampler::Resample(float* destination, int frames) {
  DCHECK(HasEnoughData(frames));

  int remaining_frames = frames;

  // Step (1) -- Prime the input buffer at the start of the input stream.
  if (!buffer_primed_) {
    Read(r0_, kBlockSize + kKernelSize / 2);
    buffer_primed_ = true;
  }

  // Step (2) -- Resample!
  while (remaining_frames) {
    while (virtual_source_idx_ < kBlockSize) {
      // |virtual_source_idx_| lies in between two kernel offsets so figure out
      // what they are.
      int source_idx = static_cast<int>(virtual_source_idx_);
      double subsample_remainder = virtual_source_idx_ - source_idx;

      double virtual_offset_idx = subsample_remainder * kKernelOffsetCount;
      int offset_idx = static_cast<int>(virtual_offset_idx);

      // We'll compute "convolutions" for the two kernels which straddle
      // |virtual_source_idx_|.
      float* k1 = kernel_storage_.get() + offset_idx * kKernelSize;
      float* k2 = k1 + kKernelSize;

      // Initialize input pointer based on quantized |virtual_source_idx_|.
      float* input_ptr = r1_ + source_idx * channel_count_;

      // Figure out how much to weight each kernel's "convolution".
      double kernel_interpolation_factor = virtual_offset_idx - offset_idx;
      for (int i = 0; i < channel_count_; ++i) {
        *destination++ =
            Convolve(input_ptr + i, k1, k2, kernel_interpolation_factor);
      }

      // Advance the virtual index.
      virtual_source_idx_ += io_sample_rate_ratio_;

      if (!--remaining_frames) {
        frames_resampled_ += frames;
        return;
      }
    }

    // Wrap back around to the start.
    virtual_source_idx_ -= kBlockSize;

    // Step (3) Copy r3_ to r1_ and r4_ to r2_.
    // This wraps the last input frames back to the start of the buffer.
    memcpy(r1_, r3_, frame_size_in_bytes_ * (kKernelSize / 2));
    memcpy(r2_, r4_, frame_size_in_bytes_ * (kKernelSize / 2));

    // Step (4)
    // Refresh the buffer with more input.
    Read(r5_, kBlockSize);
  }

  NOTREACHED();
}

void InterleavedSincResampler::Flush() {
  virtual_source_idx_ = 0;
  buffer_primed_ = false;
  memset(input_buffer_.get(), 0, frame_size_in_bytes_ * kBufferSize);
  while (!pending_buffers_.empty()) {
    pending_buffers_.pop();
  }
  offset_in_frames_ = 0;
  frames_resampled_ = 0;
  frames_queued_ = 0;
}

bool InterleavedSincResampler::CanQueueBuffer() const {
  if (pending_buffers_.empty()) {
    return true;
  }
  if (pending_buffers_.back()->IsEndOfStream()) {
    return false;
  }
  return pending_buffers_.size() < kMaximumPendingBuffers;
}

bool InterleavedSincResampler::ReachedEOS() const {
  if (pending_buffers_.empty() || !pending_buffers_.back()->IsEndOfStream()) {
    return false;
  }
  return frames_resampled_ * io_sample_rate_ratio_ >= frames_queued_;
}

bool InterleavedSincResampler::HasEnoughData(int frames_to_resample) const {
  // Always return true if EOS is seen, as in this case we will just fill 0.
  if (!pending_buffers_.empty() && pending_buffers_.back()->IsEndOfStream()) {
    return true;
  }

  // We have to decrease frames_queued_ down as the Read()s are always done in
  // blocks of kBlockSize or kBufferSize. We have to ensure that there is buffer
  // for an extra Read().
  return (frames_resampled_ + frames_to_resample) * io_sample_rate_ratio_ <
         frames_queued_ - kBufferSize;
}

void InterleavedSincResampler::Read(float* destination, int frames) {
  while (frames > 0 && !pending_buffers_.empty()) {
    scoped_refptr<Buffer> buffer = pending_buffers_.front();
    if (buffer->IsEndOfStream()) {
      // Zero fill the buffer after EOS has reached.
      memset(destination, 0, frame_size_in_bytes_ * frames);
      return;
    }
    // Copy the data over.
    int frames_in_buffer = buffer->GetNumFrames();
    int frames_to_copy = std::min(frames_in_buffer - offset_in_frames_, frames);
    const float* source = buffer->GetData();
    source += offset_in_frames_ * channel_count_;
    memcpy(destination, source, frame_size_in_bytes_ * frames_to_copy);
    offset_in_frames_ += frames_to_copy;
    // Pop the first buffer if all its content has been read.
    if (offset_in_frames_ == frames_in_buffer) {
      offset_in_frames_ = 0;
      pending_buffers_.pop();
    }
    frames -= frames_to_copy;
    destination += frames_to_copy * channel_count_;
  }

  // Read should always be satisfied as otherwise Resample should return false
  // to the caller directly.
  DCHECK_EQ(frames, 0);
}

float InterleavedSincResampler::Convolve(const float* input_ptr,
                                         const float* k1, const float* k2,
                                         double kernel_interpolation_factor) {
  float sum1 = 0;
  float sum2 = 0;

  // Generate a single output sample.  Unrolling this loop hurt performance in
  // local testing.
  int n = kKernelSize;
  while (n--) {
    sum1 += *input_ptr * *k1++;
    sum2 += *input_ptr * *k2++;
    input_ptr += channel_count_;
  }

  // Linearly interpolate the two "convolutions".
  return (1.0 - kernel_interpolation_factor) * sum1 +
         kernel_interpolation_factor * sum2;
}

}  // namespace media
}  // namespace cobalt
