/*
 *  Copyright (c) 2014 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.
 */

//
//  Command line tool for speech intelligibility enhancement. Provides for
//  running and testing intelligibility_enhancer as an independent process.
//  Use --help for options.
//

#include <stdint.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>

#include "gflags/gflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/checks.h"
#include "webrtc/common_audio/real_fourier.h"
#include "webrtc/common_audio/wav_file.h"
#include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhancer.h"
#include "webrtc/modules/audio_processing/intelligibility/intelligibility_utils.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/test/testsupport/fileutils.h"

using std::complex;
using webrtc::intelligibility::VarianceArray;

namespace webrtc {
namespace {

bool ValidateClearWindow(const char* flagname, int32_t value) {
  return value > 0;
}

DEFINE_int32(clear_type,
             webrtc::intelligibility::VarianceArray::kStepDecaying,
             "Variance algorithm for clear data.");
DEFINE_double(clear_alpha, 0.9, "Variance decay factor for clear data.");
DEFINE_int32(clear_window,
             475,
             "Window size for windowed variance for clear data.");
const bool clear_window_dummy =
    google::RegisterFlagValidator(&FLAGS_clear_window, &ValidateClearWindow);
DEFINE_int32(sample_rate,
             16000,
             "Audio sample rate used in the input and output files.");
DEFINE_int32(ana_rate,
             800,
             "Analysis rate; gains recalculated every N blocks.");
DEFINE_int32(
    var_rate,
    2,
    "Variance clear rate; history is forgotten every N gain recalculations.");
DEFINE_double(gain_limit, 1000.0, "Maximum gain change in one block.");

DEFINE_string(clear_file, "speech.wav", "Input file with clear speech.");
DEFINE_string(noise_file, "noise.wav", "Input file with noise data.");
DEFINE_string(out_file,
              "proc_enhanced.wav",
              "Enhanced output. Use '-' to "
              "play through aplay immediately.");

const int kNumChannels = 1;

// void function for gtest
void void_main(int argc, char* argv[]) {
  google::SetUsageMessage(
      "\n\nVariance algorithm types are:\n"
      "  0 - infinite/normal,\n"
      "  1 - exponentially decaying,\n"
      "  2 - rolling window.\n"
      "\nInput files must be little-endian 16-bit signed raw PCM.\n");
  google::ParseCommandLineFlags(&argc, &argv, true);

  size_t samples;        // Number of samples in input PCM file
  size_t fragment_size;  // Number of samples to process at a time
                         // to simulate APM stream processing

  // Load settings and wav input.

  fragment_size = FLAGS_sample_rate / 100;  // Mirror real time APM chunk size.
                                            // Duplicates chunk_length_ in
                                            // IntelligibilityEnhancer.

  struct stat in_stat, noise_stat;
  ASSERT_EQ(stat(FLAGS_clear_file.c_str(), &in_stat), 0)
      << "Empty speech file.";
  ASSERT_EQ(stat(FLAGS_noise_file.c_str(), &noise_stat), 0)
      << "Empty noise file.";

  samples = std::min(in_stat.st_size, noise_stat.st_size) / 2;

  WavReader in_file(FLAGS_clear_file);
  std::vector<float> in_fpcm(samples);
  in_file.ReadSamples(samples, &in_fpcm[0]);

  WavReader noise_file(FLAGS_noise_file);
  std::vector<float> noise_fpcm(samples);
  noise_file.ReadSamples(samples, &noise_fpcm[0]);

  // Run intelligibility enhancement.
  IntelligibilityEnhancer::Config config;
  config.sample_rate_hz = FLAGS_sample_rate;
  config.var_type = static_cast<VarianceArray::StepType>(FLAGS_clear_type);
  config.var_decay_rate = static_cast<float>(FLAGS_clear_alpha);
  config.var_window_size = static_cast<size_t>(FLAGS_clear_window);
  config.analysis_rate = FLAGS_ana_rate;
  config.gain_change_limit = FLAGS_gain_limit;
  IntelligibilityEnhancer enh(config);

  // Slice the input into smaller chunks, as the APM would do, and feed them
  // through the enhancer.
  float* clear_cursor = &in_fpcm[0];
  float* noise_cursor = &noise_fpcm[0];

  for (size_t i = 0; i < samples; i += fragment_size) {
    enh.AnalyzeCaptureAudio(&noise_cursor, FLAGS_sample_rate, kNumChannels);
    enh.ProcessRenderAudio(&clear_cursor, FLAGS_sample_rate, kNumChannels);
    clear_cursor += fragment_size;
    noise_cursor += fragment_size;
  }

  if (FLAGS_out_file.compare("-") == 0) {
    const std::string temp_out_filename =
        test::TempFilename(test::WorkingDir(), "temp_wav_file");
    {
      WavWriter out_file(temp_out_filename, FLAGS_sample_rate, kNumChannels);
      out_file.WriteSamples(&in_fpcm[0], samples);
    }
    system(("aplay " + temp_out_filename).c_str());
    system(("rm " + temp_out_filename).c_str());
  } else {
    WavWriter out_file(FLAGS_out_file, FLAGS_sample_rate, kNumChannels);
    out_file.WriteSamples(&in_fpcm[0], samples);
  }
}

}  // namespace
}  // namespace webrtc

int main(int argc, char* argv[]) {
  webrtc::void_main(argc, argv);
  return 0;
}
