/*
 *  Copyright (c) 2012 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 <cmath>
#include <cstdio>

#include <algorithm>

#include "gflags/gflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/audio_processing/agc/agc.h"
#include "webrtc/modules/audio_processing/agc/utility.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/test/testsupport/trace_to_stderr.h"
#include "webrtc/tools/agc/agc_manager.h"
#include "webrtc/tools/agc/test_utils.h"
#include "webrtc/voice_engine/mock/fake_voe_external_media.h"
#include "webrtc/voice_engine/mock/mock_voe_volume_control.h"

DEFINE_string(in, "in.pcm", "input filename");
DEFINE_string(out, "out.pcm", "output filename");
DEFINE_int32(rate, 16000, "sample rate in Hz");
DEFINE_int32(channels, 1, "number of channels");
DEFINE_int32(level, -18, "target level in RMS dBFs [-100, 0]");
DEFINE_bool(limiter, true, "enable a limiter for the compression stage");
DEFINE_int32(cmp_level, 2, "target level in dBFs for the compression stage");
DEFINE_int32(mic_gain, 80, "range of gain provided by the virtual mic in dB");
DEFINE_int32(gain_offset, 0,
             "an amount (in dB) to add to every entry in the gain map");
DEFINE_string(gain_file, "",
    "filename providing a mic gain mapping. The file should be text containing "
    "a (floating-point) gain entry in dBFs per line corresponding to levels "
    "from 0 to 255.");

using ::testing::_;
using ::testing::ByRef;
using ::testing::DoAll;
using ::testing::Mock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgReferee;

namespace webrtc {
namespace {

const char kUsage[] = "\nProcess an audio file to simulate an analog agc.";

void ReadGainMapFromFile(FILE* file, int offset, int gain_map[256]) {
  for (int i = 0; i < 256; ++i) {
    float gain = 0;
    ASSERT_EQ(1, fscanf(file, "%f", &gain));
    gain_map[i] = std::floor(gain + 0.5);
  }

  // Adjust from dBFs to gain in dB. We assume that level 127 provides 0 dB
  // gain. This corresponds to the interpretation in MicLevel2Gain().
  const int midpoint = gain_map[127];
  printf("Gain map\n");
  for (int i = 0; i < 256; ++i) {
    gain_map[i] += offset - midpoint;
    if (i % 5 == 0) {
      printf("%d: %d dB\n", i, gain_map[i]);
    }
  }
}

void CalculateGainMap(int gain_range_db, int offset, int gain_map[256]) {
  printf("Gain map\n");
  for (int i = 0; i < 256; ++i) {
    gain_map[i] = std::floor(MicLevel2Gain(gain_range_db, i) + 0.5) + offset;
    if (i % 5 == 0) {
      printf("%d: %d dB\n", i, gain_map[i]);
    }
  }
}

void RunAgc() {
  test::TraceToStderr trace_to_stderr(true);
  FILE* in_file = fopen(FLAGS_in.c_str(), "rb");
  ASSERT_TRUE(in_file != NULL);
  FILE* out_file = fopen(FLAGS_out.c_str(), "wb");
  ASSERT_TRUE(out_file != NULL);

  int gain_map[256];
  if (!FLAGS_gain_file.empty()) {
    FILE* gain_file = fopen(FLAGS_gain_file.c_str(), "rt");
    ASSERT_TRUE(gain_file != NULL);
    ReadGainMapFromFile(gain_file, FLAGS_gain_offset, gain_map);
    fclose(gain_file);
  } else {
    CalculateGainMap(FLAGS_mic_gain, FLAGS_gain_offset, gain_map);
  }

  FakeVoEExternalMedia media;
  MockVoEVolumeControl volume;
  Agc* agc = new Agc;
  AudioProcessing* audioproc = AudioProcessing::Create();
  ASSERT_TRUE(audioproc != NULL);
  AgcManager manager(&media, &volume, agc, audioproc);

  int mic_level = 128;
  int last_mic_level = mic_level;
  EXPECT_CALL(volume, GetMicVolume(_))
      .WillRepeatedly(DoAll(SetArgReferee<0>(ByRef(mic_level)), Return(0)));
  EXPECT_CALL(volume, SetMicVolume(_))
      .WillRepeatedly(DoAll(SaveArg<0>(&mic_level), Return(0)));

  manager.Enable(true);
  ASSERT_EQ(0, agc->set_target_level_dbfs(FLAGS_level));
  const AudioProcessing::Error kNoErr = AudioProcessing::kNoError;
  GainControl* gctrl = audioproc->gain_control();
  ASSERT_EQ(kNoErr, gctrl->set_target_level_dbfs(FLAGS_cmp_level));
  ASSERT_EQ(kNoErr, gctrl->enable_limiter(FLAGS_limiter));

  AudioFrame frame;
  frame.num_channels_ = FLAGS_channels;
  frame.sample_rate_hz_ = FLAGS_rate;
  frame.samples_per_channel_ = FLAGS_rate / 100;
  const size_t frame_length = frame.samples_per_channel_ * FLAGS_channels;
  size_t sample_count = 0;
  while (fread(frame.data_, sizeof(int16_t), frame_length, in_file) ==
      frame_length) {
    SimulateMic(gain_map, mic_level, last_mic_level, &frame);
    last_mic_level = mic_level;
    media.CallProcess(kRecordingAllChannelsMixed, frame.data_,
                      frame.samples_per_channel_, FLAGS_rate, FLAGS_channels);
    ASSERT_EQ(frame_length,
              fwrite(frame.data_, sizeof(int16_t), frame_length, out_file));
    sample_count += frame_length;
    trace_to_stderr.SetTimeSeconds(static_cast<float>(sample_count) /
                                   FLAGS_channels / FLAGS_rate);
  }
  fclose(in_file);
  fclose(out_file);
  EXPECT_CALL(volume, Release());
}

}  // namespace
}  // namespace webrtc

int main(int argc, char* argv[]) {
  google::SetUsageMessage(webrtc::kUsage);
  google::ParseCommandLineFlags(&argc, &argv, true);
  webrtc::RunAgc();
  return 0;
}
