/*
 *  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 <cfloat>
#include <cstdio>
#include <cstdlib>
#include <vector>

#include "webrtc/modules/audio_processing/transient/transient_detector.h"
#include "webrtc/modules/audio_processing/transient/file_utils.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/system_wrappers/include/file_wrapper.h"

using rtc::scoped_ptr;
using webrtc::FileWrapper;
using webrtc::TransientDetector;

// Application to generate a RTP timing file.
// Opens the PCM file and divides the signal in frames.
// Creates a send times array, one for each step.
// Each block that contains a transient, has an infinite send time.
// The resultant array is written to a DAT file
// Returns -1 on error or |lost_packets| otherwise.
int main(int argc, char* argv[]) {
  if (argc != 5) {
    printf("\n%s - Application to generate a RTP timing file.\n\n", argv[0]);
    printf("%s PCMfile DATfile chunkSize sampleRate\n\n", argv[0]);
    printf("Opens the PCMfile with sampleRate in Hertz.\n");
    printf("Creates a send times array, one for each chunkSize ");
    printf("milliseconds step.\n");
    printf("Each block that contains a transient, has an infinite send time. ");
    printf("The resultant array is written to a DATfile.\n\n");
    return 0;
  }

  scoped_ptr<FileWrapper> pcm_file(FileWrapper::Create());
  pcm_file->OpenFile(argv[1], true, false, false);
  if (!pcm_file->Open()) {
    printf("\nThe %s could not be opened.\n\n", argv[1]);
    return -1;
  }

  scoped_ptr<FileWrapper> dat_file(FileWrapper::Create());
  dat_file->OpenFile(argv[2], false, false, false);
  if (!dat_file->Open()) {
    printf("\nThe %s could not be opened.\n\n", argv[2]);
    return -1;
  }

  int chunk_size_ms = atoi(argv[3]);
  if (chunk_size_ms <= 0) {
    printf("\nThe chunkSize must be a positive integer\n\n");
    return -1;
  }

  int sample_rate_hz = atoi(argv[4]);
  if (sample_rate_hz <= 0) {
    printf("\nThe sampleRate must be a positive integer\n\n");
    return -1;
  }

  TransientDetector detector(sample_rate_hz);
  int lost_packets = 0;
  size_t audio_buffer_length = chunk_size_ms * sample_rate_hz / 1000;
  scoped_ptr<float[]> audio_buffer(new float[audio_buffer_length]);
  std::vector<float> send_times;

  // Read first buffer from the PCM test file.
  size_t file_samples_read = ReadInt16FromFileToFloatBuffer(
      pcm_file.get(),
      audio_buffer_length,
      audio_buffer.get());
  for (int time = 0; file_samples_read > 0; time += chunk_size_ms) {
    // Pad the rest of the buffer with zeros.
    for (size_t i = file_samples_read; i < audio_buffer_length; ++i) {
      audio_buffer[i] = 0.0;
    }
    float value =
        detector.Detect(audio_buffer.get(), audio_buffer_length, NULL, 0);
    if (value < 0.5f) {
      value = time;
    } else {
      value = FLT_MAX;
      ++lost_packets;
    }
    send_times.push_back(value);

    // Read next buffer from the PCM test file.
    file_samples_read = ReadInt16FromFileToFloatBuffer(pcm_file.get(),
                                                       audio_buffer_length,
                                                       audio_buffer.get());
  }

  size_t floats_written = WriteFloatBufferToFile(dat_file.get(),
                                                 send_times.size(),
                                                 &send_times[0]);

  if (floats_written == 0) {
    printf("\nThe send times could not be written to DAT file\n\n");
    return -1;
  }

  pcm_file->CloseFile();
  dat_file->CloseFile();

  return lost_packets;
}
