/*
 *  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/interface/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;
}
