/*
 *  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 "modules/audio_coding/neteq/tools/input_audio_file.h"

#include "rtc_base/checks.h"

namespace webrtc {
namespace test {

InputAudioFile::InputAudioFile(const std::string file_name, bool loop_at_end)
    : loop_at_end_(loop_at_end) {
  fp_ = fopen(file_name.c_str(), "rb");
}

InputAudioFile::~InputAudioFile() { fclose(fp_); }

bool InputAudioFile::Read(size_t samples, int16_t* destination) {
  if (!fp_) {
    return false;
  }
  size_t samples_read = fread(destination, sizeof(int16_t), samples, fp_);
  if (samples_read < samples) {
    if (!loop_at_end_) {
      return false;
    }
    // Rewind and read the missing samples.
    rewind(fp_);
    size_t missing_samples = samples - samples_read;
    if (fread(destination + samples_read, sizeof(int16_t), missing_samples,
              fp_) < missing_samples) {
      // Could not read enough even after rewinding the file.
      return false;
    }
  }
  return true;
}

bool InputAudioFile::Seek(int samples) {
  if (!fp_) {
    return false;
  }
  // Find file boundaries.
  const long current_pos = ftell(fp_);
  RTC_CHECK_NE(EOF, current_pos)
      << "Error returned when getting file position.";
  RTC_CHECK_EQ(0, fseek(fp_, 0, SEEK_END));  // Move to end of file.
  const long file_size = ftell(fp_);
  RTC_CHECK_NE(EOF, file_size) << "Error returned when getting file position.";
  // Find new position.
  long new_pos = current_pos + sizeof(int16_t) * samples;  // Samples to bytes.
  if (loop_at_end_) {
    new_pos = new_pos % file_size;  // Wrap around the end of the file.
    if (new_pos < 0) {
      // For negative values of new_pos, newpos % file_size will also be
      // negative. To get the correct result it's needed to add file_size.
      new_pos += file_size;
    }
  } else {
    new_pos = new_pos > file_size ? file_size : new_pos;  // Don't loop.
  }
  RTC_CHECK_GE(new_pos, 0)
      << "Trying to move to before the beginning of the file";
  // Move to new position relative to the beginning of the file.
  RTC_CHECK_EQ(0, fseek(fp_, new_pos, SEEK_SET));
  return true;
}

void InputAudioFile::DuplicateInterleaved(const int16_t* source, size_t samples,
                                          size_t channels,
                                          int16_t* destination) {
  // Start from the end of |source| and |destination|, and work towards the
  // beginning. This is to allow in-place interleaving of the same array (i.e.,
  // |source| and |destination| are the same array).
  for (int i = static_cast<int>(samples - 1); i >= 0; --i) {
    for (int j = static_cast<int>(channels - 1); j >= 0; --j) {
      destination[i * channels + j] = source[i];
    }
  }
}

}  // namespace test
}  // namespace webrtc
