/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <algorithm>
#include "third_party/blink/renderer/platform/audio/reverb_accumulation_buffer.h"
#include "third_party/blink/renderer/platform/audio/vector_math.h"

namespace blink {

using namespace vector_math;

ReverbAccumulationBuffer::ReverbAccumulationBuffer(size_t length)
    : buffer_(length), read_index_(0), read_time_frame_(0) {}

void ReverbAccumulationBuffer::ReadAndClear(float* destination,
                                            size_t number_of_frames) {
  size_t buffer_length = buffer_.size();
  bool is_copy_safe =
      read_index_ <= buffer_length && number_of_frames <= buffer_length;

  DCHECK(is_copy_safe);
  if (!is_copy_safe)
    return;

  size_t frames_available = buffer_length - read_index_;
  size_t number_of_frames1 = std::min(number_of_frames, frames_available);
  size_t number_of_frames2 = number_of_frames - number_of_frames1;

  float* source = buffer_.Data();
  memcpy(destination, source + read_index_, sizeof(float) * number_of_frames1);
  memset(source + read_index_, 0, sizeof(float) * number_of_frames1);

  // Handle wrap-around if necessary
  if (number_of_frames2 > 0) {
    memcpy(destination + number_of_frames1, source,
           sizeof(float) * number_of_frames2);
    memset(source, 0, sizeof(float) * number_of_frames2);
  }

  read_index_ = (read_index_ + number_of_frames) % buffer_length;
  read_time_frame_ += number_of_frames;
}

void ReverbAccumulationBuffer::UpdateReadIndex(int* read_index,
                                               size_t number_of_frames) const {
  // Update caller's readIndex
  *read_index = (*read_index + number_of_frames) % buffer_.size();
}

int ReverbAccumulationBuffer::Accumulate(float* source,
                                         size_t number_of_frames,
                                         int* read_index,
                                         size_t delay_frames) {
  size_t buffer_length = buffer_.size();

  size_t write_index = (*read_index + delay_frames) % buffer_length;

  // Update caller's readIndex
  *read_index = (*read_index + number_of_frames) % buffer_length;

  size_t frames_available = buffer_length - write_index;
  size_t number_of_frames1 = std::min(number_of_frames, frames_available);
  size_t number_of_frames2 = number_of_frames - number_of_frames1;

  float* destination = buffer_.Data();

  bool is_safe = write_index <= buffer_length &&
                 number_of_frames1 + write_index <= buffer_length &&
                 number_of_frames2 <= buffer_length;
  DCHECK(is_safe);
  if (!is_safe)
    return 0;

  Vadd(source, 1, destination + write_index, 1, destination + write_index, 1,
       number_of_frames1);

  // Handle wrap-around if necessary
  if (number_of_frames2 > 0)
    Vadd(source + number_of_frames1, 1, destination, 1, destination, 1,
         number_of_frames2);

  return write_index;
}

void ReverbAccumulationBuffer::Reset() {
  buffer_.Zero();
  read_index_ = 0;
  read_time_frame_ = 0;
}

}  // namespace blink
