// Copyright 2018 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.

#include "services/audio/delay_buffer.h"

#include <algorithm>
#include <utility>

#include "base/numerics/safe_conversions.h"
#include "media/base/audio_bus.h"
#include "media/base/vector_math.h"

namespace audio {

DelayBuffer::DelayBuffer(int history_size) : history_size_(history_size) {}

DelayBuffer::~DelayBuffer() = default;

void DelayBuffer::Write(FrameTicks position,
                        const media::AudioBus& input_bus,
                        double volume) {
  DCHECK(chunks_.empty() || chunks_.back().GetEndPosition() <= position);

  // Prune-out the oldest InputChunks, but ensure that this DelayBuffer is
  // maintaining at least |history_size_| frames in total when this method
  // returns (i.e., after the current chunk is inserted).
  const FrameTicks prune_position =
      position + input_bus.frames() - history_size_;
  while (!chunks_.empty() &&
         chunks_.front().GetEndPosition() <= prune_position) {
    chunks_.pop_front();
  }

  // Make a copy of the AudioBus for later consumption. Apply the volume setting
  // by scaling the audio signal during the copy.
  auto copy = media::AudioBus::Create(input_bus.channels(), input_bus.frames());
  for (int ch = 0; ch < input_bus.channels(); ++ch) {
    media::vector_math::FMUL(input_bus.channel(ch), volume, input_bus.frames(),
                             copy->channel(ch));
  }

  chunks_.emplace_back(position, std::move(copy));
}

void DelayBuffer::Read(FrameTicks from,
                       int frames_to_read,
                       media::AudioBus* output_bus) {
  DCHECK_LE(frames_to_read, output_bus->frames());

  // Remove all of the oldest chunks until the one in front contains the |from|
  // position (or is the first chunk after it).
  while (!chunks_.empty() && chunks_.front().GetEndPosition() <= from) {
    chunks_.pop_front();
  }

  // Loop, transferring data from each InputChunk to the output AudioBus until
  // the requested number of frames have been read.
  for (int frames_remaining = frames_to_read; frames_remaining > 0;) {
    const int dest_offset = frames_to_read - frames_remaining;

    // If attempting to read past the end of the recorded signal, zero-pad the
    // rest of the output and return.
    if (chunks_.empty()) {
      output_bus->ZeroFramesPartial(dest_offset, frames_remaining);
      return;
    }
    const InputChunk& chunk = chunks_.front();

    // This is the offset to the frame within the chunk's AudioBus that
    // corresponds to the offset in the output AudioBus. If this calculated
    // value is out-of-range, there is a gap (i.e., a missing piece of audio
    // signal) in the recording.
    const int source_offset =
        base::saturated_cast<int>(from + dest_offset - chunk.position);

    if (source_offset < 0) {
      // There is a gap in the recording. Fill zeroes in the corresponding part
      // of the output.
      const int frames_to_zero_fill = (source_offset + frames_remaining <= 0)
                                          ? frames_remaining
                                          : -source_offset;
      output_bus->ZeroFramesPartial(dest_offset, frames_to_zero_fill);
      frames_remaining -= frames_to_zero_fill;
      continue;
    }
    DCHECK_LE(source_offset, chunk.bus->frames());

    // Copy some or all of the frames in the current chunk to the output; the
    // lesser of: a) the frames available in the chunk, or b) the frames
    // remaining to output.
    const int frames_to_copy_from_chunk = chunk.bus->frames() - source_offset;
    if (frames_to_copy_from_chunk <= frames_remaining) {
      chunk.bus->CopyPartialFramesTo(source_offset, frames_to_copy_from_chunk,
                                     dest_offset, output_bus);
      frames_remaining -= frames_to_copy_from_chunk;
      chunks_.pop_front();  // All frames from this chunk have been consumed.
    } else {
      chunk.bus->CopyPartialFramesTo(source_offset, frames_remaining,
                                     dest_offset, output_bus);
      return;  // The |output_bus| has been fully populated.
    }
  }
}

DelayBuffer::FrameTicks DelayBuffer::GetBeginPosition() const {
  return chunks_.empty() ? 0 : chunks_.front().position;
}

DelayBuffer::FrameTicks DelayBuffer::GetEndPosition() const {
  return chunks_.empty() ? 0 : chunks_.back().GetEndPosition();
}

DelayBuffer::InputChunk::InputChunk(FrameTicks p,
                                    std::unique_ptr<media::AudioBus> b)
    : position(p), bus(std::move(b)) {}
DelayBuffer::InputChunk::InputChunk(DelayBuffer::InputChunk&&) = default;
DelayBuffer::InputChunk& DelayBuffer::InputChunk::operator=(
    DelayBuffer::InputChunk&&) = default;
DelayBuffer::InputChunk::~InputChunk() = default;

DelayBuffer::FrameTicks DelayBuffer::InputChunk::GetEndPosition() const {
  return position + bus->frames();
}

}  // namespace audio
