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

#include <cstring>

#include "webrtc/common_audio/include/audio_util.h"
#include "webrtc/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
