/*
 *  Copyright (c) 2013 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/resampler/push_sinc_resampler.h"

#include <cstring>

#include "common_audio/include/audio_util.h"
#include "rtc_base/checks.h"

namespace webrtc {

PushSincResampler::PushSincResampler(size_t source_frames,
                                     size_t destination_frames)
    : resampler_(new SincResampler(source_frames * 1.0 / destination_frames,
                                   source_frames,
                                   this)),
      source_ptr_(nullptr),
      source_ptr_int_(nullptr),
      destination_frames_(destination_frames),
      first_pass_(true),
      source_available_(0) {}

PushSincResampler::~PushSincResampler() {}

size_t PushSincResampler::Resample(const int16_t* source,
                                   size_t source_length,
                                   int16_t* destination,
                                   size_t destination_capacity) {
  if (!float_buffer_.get())
    float_buffer_.reset(new float[destination_frames_]);

  source_ptr_int_ = source;
  // Pass nullptr as the float source to have Run() read from the int16 source.
  Resample(nullptr, source_length, float_buffer_.get(), destination_frames_);
  FloatS16ToS16(float_buffer_.get(), destination_frames_, destination);
  source_ptr_int_ = nullptr;
  return destination_frames_;
}

size_t PushSincResampler::Resample(const float* source,
                                   size_t source_length,
                                   float* destination,
                                   size_t destination_capacity) {
  RTC_CHECK_EQ(source_length, resampler_->request_frames());
  RTC_CHECK_GE(destination_capacity, destination_frames_);
  // Cache the source pointer. Calling Resample() will immediately trigger
  // the Run() callback whereupon we provide the cached value.
  source_ptr_ = source;
  source_available_ = source_length;

  // On the first pass, we call Resample() twice. During the first call, we
  // provide dummy input and discard the output. This is done to prime the
  // SincResampler buffer with the correct delay (half the kernel size), thereby
  // ensuring that all later Resample() calls will only result in one input
  // request through Run().
  //
  // If this wasn't done, SincResampler would call Run() twice on the first
  // pass, and we'd have to introduce an entire |source_frames| of delay, rather
  // than the minimum half kernel.
  //
  // It works out that ChunkSize() is exactly the amount of output we need to
  // request in order to prime the buffer with a single Run() request for
  // |source_frames|.
  if (first_pass_)
    resampler_->Resample(resampler_->ChunkSize(), destination);

  resampler_->Resample(destination_frames_, destination);
  source_ptr_ = nullptr;
  return destination_frames_;
}

void PushSincResampler::Run(size_t frames, float* destination) {
  // Ensure we are only asked for the available samples. This would fail if
  // Run() was triggered more than once per Resample() call.
  RTC_CHECK_EQ(source_available_, frames);

  if (first_pass_) {
    // Provide dummy input on the first pass, the output of which will be
    // discarded, as described in Resample().
    std::memset(destination, 0, frames * sizeof(*destination));
    first_pass_ = false;
    return;
  }

  if (source_ptr_) {
    std::memcpy(destination, source_ptr_, frames * sizeof(*destination));
  } else {
    for (size_t i = 0; i < frames; ++i)
      destination[i] = static_cast<float>(source_ptr_int_[i]);
  }
  source_available_ -= frames;
}

}  // namespace webrtc
