// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>

#include <ctime>

#include "base/command_line.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/scoped_native_library.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/media/webrtc_browsertest_audio.h"
#include "chrome/browser/media/webrtc_browsertest_base.h"
#include "chrome/browser/media/webrtc_browsertest_common.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "media/base/audio_parameters.h"
#include "media/base/media_switches.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/perf/perf_test.h"

namespace {

static const base::FilePath::CharType kReferenceFile[] =
    FILE_PATH_LITERAL("speech_44kHz_16bit_stereo.wav");

// The javascript will load the reference file relative to its location,
// which is in /webrtc on the web server. The files we are looking for are in
// webrtc/resources in the chrome/test/data folder.
static const char kReferenceFileRelativeUrl[] =
    "resources/speech_44kHz_16bit_stereo.wav";

static const char kWebRtcAudioTestHtmlPage[] =
    "/webrtc/webrtc_audio_quality_test.html";

// For the AGC test, there are 6 speech segments split on silence. If one
// segment is significantly different in length compared to the same segment in
// the reference file, there's something fishy going on.
const int kMaxAgcSegmentDiffMs =
#if defined(OS_MACOSX)
  // Something is different on Mac; http://crbug.com/477653.
  600;
#else
  200;
#endif

#if defined(OS_LINUX) || defined(OS_MACOSX)
#define MAYBE_WebRtcAudioQualityBrowserTest WebRtcAudioQualityBrowserTest
#else
// Not implemented on Android, ChromeOS etc.
// Disabled on win while bots are configured: http://crbug.com/625808.
#define MAYBE_WebRtcAudioQualityBrowserTest DISABLED_WebRtcAudioQualityBrowserTest
#endif

}  // namespace

// Test we can set up a WebRTC call and play audio through it.
//
// If you're not a googler and want to run this test, you need to provide a
// pesq binary for your platform (and sox.exe on windows). Read more on how
// resources are managed in chrome/test/data/webrtc/resources/README.
//
// This test will only work on machines that have been configured to record
// their own input.
//
// On Linux:
// 1. # sudo apt-get install pavucontrol sox
// 2. For the user who will run the test: # pavucontrol
// 3. In a separate terminal, # arecord dummy
// 4. In pavucontrol, go to the recording tab.
// 5. For the ALSA plugin [aplay]: ALSA Capture from, change from <x> to
//    <Monitor of x>, where x is whatever your primary sound device is called.
// 6. Try launching chrome as the target user on the target machine, try
//    playing, say, a YouTube video, and record with # arecord -f dat tmp.dat.
//    Verify the recording with aplay (should have recorded what you played
//    from chrome).
//
// Note: the volume for ALL your input devices will be forced to 100% by
//       running this test on Linux.
//
// On Mac:
// TODO(phoglund): download sox from gs instead.
// 1. Get SoundFlower: http://rogueamoeba.com/freebies/soundflower/download.php
// 2. Install it + reboot.
// 3. Install MacPorts (http://www.macports.org/).
// 4. Install sox: sudo port install sox.
// 5. (For Chrome bots) Ensure sox and rec are reachable from the env the test
//    executes in (sox and rec tends to install in /opt/, which generally isn't
//    in the Chrome bots' env). For instance, run
//    sudo ln -s /opt/local/bin/rec /usr/local/bin/rec
//    sudo ln -s /opt/local/bin/sox /usr/local/bin/sox
// 6. In Sound Preferences, set both input and output to Soundflower (2ch).
//    Note: You will no longer hear audio on this machine, and it will no
//    longer use any built-in mics.
// 7. Try launching chrome as the target user on the target machine, try
//    playing, say, a YouTube video, and record with 'rec test.wav trim 0 5'.
//    Stop the video in chrome and try playing back the file; you should hear
//    a recording of the video (note; if you play back on the target machine
//    you must revert the changes in step 3 first).
//
// On Windows 7:
// 1. Control panel > Sound > Manage audio devices.
// 2. In the recording tab, right-click in an empty space in the pane with the
//    devices. Tick 'show disabled devices'.
// 3. You should see a 'stero mix' device - this is what your speakers output.
//    Right click > Properties.
// 4. In the Listen tab for the mix device, check the 'listen to this device'
//    checkbox. Ensure the mix device is the default recording device.
// 5. Launch chrome and try playing a video with sound. You should see
//    in the volume meter for the mix device. Configure the mix device to have
//    50 / 100 in level. Also go into the playback tab, right-click Speakers,
//    and set that level to 50 / 100. Otherwise you will get distortion in
//    the recording.
class MAYBE_WebRtcAudioQualityBrowserTest : public WebRtcTestBase {
 public:
  MAYBE_WebRtcAudioQualityBrowserTest() {}
  void SetUpInProcessBrowserTestFixture() override {
    DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    EXPECT_FALSE(command_line->HasSwitch(
        switches::kUseFakeUIForMediaStream));

    // The WebAudio-based tests don't care what devices are available to
    // getUserMedia, and the getUserMedia-based tests will play back a file
    // through the fake device using using --use-file-for-fake-audio-capture.
    command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);

    // Add loopback interface such that there is always connectivity.
    command_line->AppendSwitch(switches::kAllowLoopbackInPeerConnection);
  }

  void ConfigureFakeDeviceToPlayFile(const base::FilePath& wav_file_path) {
    base::CommandLine::ForCurrentProcess()->AppendSwitchNative(
        switches::kUseFileForFakeAudioCapture,
        wav_file_path.value() + FILE_PATH_LITERAL("%noloop"));
  }

  void AddAudioFileToWebAudio(const std::string& input_file_relative_url,
                              content::WebContents* tab_contents) {
    // This calls into webaudio.js.
    EXPECT_EQ("ok-added", ExecuteJavascript(
        "addAudioFile('" + input_file_relative_url + "')", tab_contents));
  }

  void PlayAudioFileThroughWebAudio(content::WebContents* tab_contents) {
    EXPECT_EQ("ok-playing", ExecuteJavascript("playAudioFile()", tab_contents));
  }

  content::WebContents* OpenPageWithoutGetUserMedia(const char* url) {
    chrome::AddTabAt(browser(), GURL(), -1, true);
    ui_test_utils::NavigateToURL(
        browser(), embedded_test_server()->GetURL(url));
    content::WebContents* tab =
        browser()->tab_strip_model()->GetActiveWebContents();

    // Prepare the peer connections manually in this test since we don't add
    // getUserMedia-derived media streams in this test like the other tests.
    EXPECT_EQ("ok-peerconnection-created",
              ExecuteJavascript("preparePeerConnection()", tab));
    return tab;
  }

  void MuteMediaElement(const std::string& element_id,
                        content::WebContents* tab_contents) {
    EXPECT_EQ("ok-muted", ExecuteJavascript(
        "setMediaElementMuted('" + element_id + "', true)", tab_contents));
  }

 protected:
  void TestAutoGainControl(const base::FilePath::StringType& reference_filename,
                           const std::string& constraints,
                           const std::string& perf_modifier);
  void SetupAndRecordAudioCall(const base::FilePath& reference_file,
                               const base::FilePath& recording,
                               const std::string& constraints,
                               const base::TimeDelta recording_time);
  void TestWithFakeDeviceGetUserMedia(const std::string& constraints,
                                      const std::string& perf_modifier);
};

namespace {

class AudioRecorder {
 public:
  AudioRecorder() {}
  ~AudioRecorder() {}

  // Starts the recording program for the specified duration. Returns true
  // on success. We record in 16-bit 44.1 kHz Stereo (mostly because that's
  // what SoundRecorder.exe will give us and we can't change that).
  bool StartRecording(base::TimeDelta recording_time,
                      const base::FilePath& output_file) {
    EXPECT_FALSE(recording_application_.IsValid())
        << "Tried to record, but is already recording.";

    int duration_sec = static_cast<int>(recording_time.InSeconds());
    base::CommandLine command_line(base::CommandLine::NO_PROGRAM);

#if defined(OS_WIN)
    // This disable is required to run SoundRecorder.exe on 64-bit Windows
    // from a 32-bit binary. We need to load the wow64 disable function from
    // the DLL since it doesn't exist on Windows XP.
    base::ScopedNativeLibrary kernel32_lib(base::FilePath(L"kernel32"));
    if (kernel32_lib.is_valid()) {
      typedef BOOL (WINAPI* Wow64DisableWow64FSRedirection)(PVOID*);
      Wow64DisableWow64FSRedirection wow_64_disable_wow_64_fs_redirection;
      wow_64_disable_wow_64_fs_redirection =
          reinterpret_cast<Wow64DisableWow64FSRedirection>(
              kernel32_lib.GetFunctionPointer(
                  "Wow64DisableWow64FsRedirection"));
      if (wow_64_disable_wow_64_fs_redirection != NULL) {
        PVOID* ignored = NULL;
        wow_64_disable_wow_64_fs_redirection(ignored);
      }
    }

    char duration_in_hms[128] = {0};
    struct tm duration_tm = {0};
    duration_tm.tm_sec = duration_sec;
    EXPECT_NE(0u, strftime(duration_in_hms, arraysize(duration_in_hms),
                           "%H:%M:%S", &duration_tm));

    command_line.SetProgram(
        base::FilePath(FILE_PATH_LITERAL("SoundRecorder.exe")));
    command_line.AppendArg("/FILE");
    command_line.AppendArgPath(output_file);
    command_line.AppendArg("/DURATION");
    command_line.AppendArg(duration_in_hms);
#elif defined(OS_MACOSX)
    command_line.SetProgram(base::FilePath("rec"));
    command_line.AppendArg("-b");
    command_line.AppendArg("16");
    command_line.AppendArg("-q");
    command_line.AppendArgPath(output_file);
    command_line.AppendArg("trim");
    command_line.AppendArg("0");
    command_line.AppendArg(base::IntToString(duration_sec));
#else
    command_line.SetProgram(base::FilePath("arecord"));
    command_line.AppendArg("-d");
    command_line.AppendArg(base::IntToString(duration_sec));
    command_line.AppendArg("-f");
    command_line.AppendArg("cd");
    command_line.AppendArg("-c");
    command_line.AppendArg("2");
    command_line.AppendArgPath(output_file);
#endif

    DVLOG(0) << "Running " << command_line.GetCommandLineString();
    recording_application_ =
        base::LaunchProcess(command_line, base::LaunchOptions());
    return recording_application_.IsValid();
  }

  // Joins the recording program. Returns true on success.
  bool WaitForRecordingToEnd() {
    int exit_code = -1;
    recording_application_.WaitForExit(&exit_code);
    return exit_code == 0;
  }
 private:
  base::Process recording_application_;
};

bool ForceMicrophoneVolumeTo100Percent() {
#if defined(OS_WIN)
  // Note: the force binary isn't in tools since it's one of our own.
  base::CommandLine command_line(test::GetReferenceFilesDir().Append(
      FILE_PATH_LITERAL("force_mic_volume_max.exe")));
  DVLOG(0) << "Running " << command_line.GetCommandLineString();
  std::string result;
  if (!base::GetAppOutput(command_line, &result)) {
    LOG(ERROR) << "Failed to set source volume: output was " << result;
    return false;
  }
#elif defined(OS_MACOSX)
  base::CommandLine command_line(
      base::FilePath(FILE_PATH_LITERAL("osascript")));
  command_line.AppendArg("-e");
  command_line.AppendArg("set volume input volume 100");
  command_line.AppendArg("-e");
  command_line.AppendArg("set volume output volume 85");

  std::string result;
  if (!base::GetAppOutput(command_line, &result)) {
    LOG(ERROR) << "Failed to set source volume: output was " << result;
    return false;
  }
#else
  // Just force the volume of, say the first 5 devices. A machine will rarely
  // have more input sources than that. This is way easier than finding the
  // input device we happen to be using.
  for (int device_index = 0; device_index < 5; ++device_index) {
    std::string result;
    const std::string kHundredPercentVolume = "65536";
    base::CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("pacmd")));
    command_line.AppendArg("set-source-volume");
    command_line.AppendArg(base::IntToString(device_index));
    command_line.AppendArg(kHundredPercentVolume);
    DVLOG(0) << "Running " << command_line.GetCommandLineString();
    if (!base::GetAppOutput(command_line, &result)) {
      LOG(ERROR) << "Failed to set source volume: output was " << result;
      return false;
    }
  }
#endif
  return true;
}

// Sox is the "Swiss army knife" of audio processing. We mainly use it for
// silence trimming. See http://sox.sourceforge.net.
base::CommandLine MakeSoxCommandLine() {
#if defined(OS_WIN)
  base::FilePath sox_path = test::GetToolForPlatform("sox");
  if (!base::PathExists(sox_path)) {
    LOG(ERROR) << "Missing sox.exe binary in " << sox_path.value()
               << "; you may have to provide this binary yourself.";
    return base::CommandLine(base::CommandLine::NO_PROGRAM);
  }
  base::CommandLine command_line(sox_path);
#else
  // TODO(phoglund): call checked-in sox rather than system sox on mac/linux.
  // Same for rec invocations on Mac, above.
  base::CommandLine command_line(base::FilePath(FILE_PATH_LITERAL("sox")));
#endif
  return command_line;
}

// Removes silence from beginning and end of the |input_audio_file| and writes
// the result to the |output_audio_file|. Returns true on success.
bool RemoveSilence(const base::FilePath& input_file,
                   const base::FilePath& output_file) {
  // SOX documentation for silence command: http://sox.sourceforge.net/sox.html
  // To remove the silence from both beginning and end of the audio file, we
  // call sox silence command twice: once on normal file and again on its
  // reverse, then we reverse the final output.
  // Silence parameters are (in sequence):
  // ABOVE_PERIODS: The period for which silence occurs. Value 1 is used for
  //                 silence at beginning of audio.
  // DURATION: the amount of time in seconds that non-silence must be detected
  //           before sox stops trimming audio.
  // THRESHOLD: value used to indicate what sample value is treats as silence.
  const char* kAbovePeriods = "1";
  const char* kDuration = "2";
  const char* kTreshold = "1.5%";

  base::CommandLine command_line = MakeSoxCommandLine();
  if (command_line.GetProgram().empty())
    return false;
  command_line.AppendArgPath(input_file);
  command_line.AppendArgPath(output_file);
  command_line.AppendArg("silence");
  command_line.AppendArg(kAbovePeriods);
  command_line.AppendArg(kDuration);
  command_line.AppendArg(kTreshold);
  command_line.AppendArg("reverse");
  command_line.AppendArg("silence");
  command_line.AppendArg(kAbovePeriods);
  command_line.AppendArg(kDuration);
  command_line.AppendArg(kTreshold);
  command_line.AppendArg("reverse");

  DVLOG(0) << "Running " << command_line.GetCommandLineString();
  std::string result;
  bool ok = base::GetAppOutput(command_line, &result);
  DVLOG(0) << "Output was:\n\n" << result;
  return ok;
}

// Looks for 0.2 second audio segments surrounded by silences under 0.3% audio
// power and splits the input file on those silences. Output files are written
// according to the output file template (e.g. /tmp/out.wav writes
// /tmp/out001.wav, /tmp/out002.wav, etc if there are two silence-padded
// regions in the file). The silences between speech segments must be at
// least 500 ms for this to be reliable.
bool SplitFileOnSilence(const base::FilePath& input_file,
                        const base::FilePath& output_file_template) {
  base::CommandLine command_line = MakeSoxCommandLine();
  if (command_line.GetProgram().empty())
    return false;

  // These are experimentally determined and work on the files we use.
  const char* kAbovePeriods = "1";
  const char* kUnderPeriods = "1";
  const char* kDuration = "0.2";
  const char* kTreshold = "0.5%";
  command_line.AppendArgPath(input_file);
  command_line.AppendArgPath(output_file_template);
  command_line.AppendArg("silence");
  command_line.AppendArg(kAbovePeriods);
  command_line.AppendArg(kDuration);
  command_line.AppendArg(kTreshold);
  command_line.AppendArg(kUnderPeriods);
  command_line.AppendArg(kDuration);
  command_line.AppendArg(kTreshold);
  command_line.AppendArg(":");
  command_line.AppendArg("newfile");
  command_line.AppendArg(":");
  command_line.AppendArg("restart");

  DVLOG(0) << "Running " << command_line.GetCommandLineString();
  std::string result;
  bool ok = base::GetAppOutput(command_line, &result);
  DVLOG(0) << "Output was:\n\n" << result;
  return ok;
}

bool CanParseAsFloat(const std::string& value) {
  return atof(value.c_str()) != 0 || value == "0";
}

// Runs PESQ to compare |reference_file| to a |actual_file|. The |sample_rate|
// can be either 16000 or 8000.
//
// PESQ is only mono-aware, so the files should preferably be recorded in mono.
// Furthermore it expects the file to be 16 rather than 32 bits, even though
// 32 bits might work. The audio bandwidth of the two files should be the same
// e.g. don't compare a 32 kHz file to a 8 kHz file.
//
// The raw score in MOS is written to |raw_mos|, whereas the MOS-LQO score is
// written to mos_lqo. The scores are returned as floats in string form (e.g.
// "3.145", etc). Returns true on success.
bool RunPesq(const base::FilePath& reference_file,
             const base::FilePath& actual_file,
             int sample_rate, std::string* raw_mos, std::string* mos_lqo) {
  // PESQ will break if the paths are too long (!).
  EXPECT_LT(reference_file.value().length(), 128u);
  EXPECT_LT(actual_file.value().length(), 128u);

  base::FilePath pesq_path = test::GetToolForPlatform("pesq");
  if (!base::PathExists(pesq_path)) {
    LOG(ERROR) << "Missing PESQ binary in " << pesq_path.value()
               << "; you may have to provide this binary yourself.";
    return false;
  }

  base::CommandLine command_line(pesq_path);
  command_line.AppendArg(base::StringPrintf("+%d", sample_rate));
  command_line.AppendArgPath(reference_file);
  command_line.AppendArgPath(actual_file);

  DVLOG(0) << "Running " << command_line.GetCommandLineString();
  std::string result;
  if (!base::GetAppOutput(command_line, &result)) {
    LOG(ERROR) << "Failed to run PESQ.";
    return false;
  }
  DVLOG(0) << "Output was:\n\n" << result;

  const std::string result_anchor = "Prediction (Raw MOS, MOS-LQO):  = ";
  std::size_t anchor_pos = result.find(result_anchor);
  if (anchor_pos == std::string::npos) {
    LOG(ERROR) << "PESQ was not able to compute a score; we probably recorded "
        << "only silence. Please check the output/input volume levels.";
    return false;
  }

  // There are two tab-separated numbers on the format x.xxx, e.g. 5 chars each.
  std::size_t first_number_pos = anchor_pos + result_anchor.length();
  *raw_mos = result.substr(first_number_pos, 5);
  EXPECT_TRUE(CanParseAsFloat(*raw_mos)) << "Failed to parse raw MOS number.";
  *mos_lqo = result.substr(first_number_pos + 5 + 1, 5);
  EXPECT_TRUE(CanParseAsFloat(*mos_lqo)) << "Failed to parse MOS LQO number.";

  return true;
}

base::FilePath CreateTemporaryWaveFile() {
  base::FilePath filename;
  EXPECT_TRUE(base::CreateTemporaryFile(&filename));
  base::FilePath wav_filename =
      filename.AddExtension(FILE_PATH_LITERAL(".wav"));
  EXPECT_TRUE(base::Move(filename, wav_filename));
  return wav_filename;
}

void DeleteFileUnlessTestFailed(const base::FilePath& path, bool recursive) {
  if (::testing::Test::HasFailure())
    printf("Test failed; keeping recording(s) at\n\t%" PRFilePath ".\n",
           path.value().c_str());
  else
    EXPECT_TRUE(base::DeleteFile(path, recursive));
}

std::vector<base::FilePath> ListWavFilesInDir(const base::FilePath& dir) {
  base::FileEnumerator files(dir, false, base::FileEnumerator::FILES,
                             FILE_PATH_LITERAL("*.wav"));

  std::vector<base::FilePath> result;
  for (base::FilePath name = files.Next(); !name.empty(); name = files.Next())
    result.push_back(name);
  return result;
}

// Splits |to_split| into sub-files based on silence. The file you use must have
// at least 500 ms periods of silence between speech segments for this to be
// reliable.
void SplitFileOnSilenceIntoDir(const base::FilePath& to_split,
                               const base::FilePath& workdir) {
  // First trim beginning and end since they are tricky for the splitter.
  base::FilePath trimmed_audio = CreateTemporaryWaveFile();

  ASSERT_TRUE(RemoveSilence(to_split, trimmed_audio));
  DVLOG(0) << "Trimmed silence: " << trimmed_audio.value() << std::endl;

  ASSERT_TRUE(SplitFileOnSilence(
      trimmed_audio, workdir.Append(FILE_PATH_LITERAL("output.wav"))));
  DeleteFileUnlessTestFailed(trimmed_audio, false);
}

// Computes the difference between the actual and reference segment. A positive
// number x means the actual file is x dB stronger than the reference.
float AnalyzeOneSegment(const base::FilePath& ref_segment,
                        const base::FilePath& actual_segment,
                        int segment_number) {
  media::AudioParameters ref_parameters;
  media::AudioParameters actual_parameters;
  float ref_energy =
      test::ComputeAudioEnergyForWavFile(ref_segment, &ref_parameters);
  float actual_energy =
      test::ComputeAudioEnergyForWavFile(actual_segment, &actual_parameters);

  base::TimeDelta difference_in_length = ref_parameters.GetBufferDuration() -
                                         actual_parameters.GetBufferDuration();

  EXPECT_LE(difference_in_length,
            base::TimeDelta::FromMilliseconds(kMaxAgcSegmentDiffMs))
      << "Segments differ " << difference_in_length.InMilliseconds() << " ms "
      << "in length for segment " << segment_number << "; we're likely "
      << "comparing unrelated segments or silence splitting is busted.";

  return actual_energy - ref_energy;
}

std::string MakeTraceName(const base::FilePath& ref_filename,
                          size_t segment_number) {
  std::string ascii_filename;
#if defined(OS_WIN)
  ascii_filename = base::WideToUTF8(ref_filename.BaseName().value());
#else
  ascii_filename = ref_filename.BaseName().value();
#endif
  return base::StringPrintf(
      "%s_segment_%d", ascii_filename.c_str(), (int)segment_number);
}

void AnalyzeSegmentsAndPrintResult(
    const std::vector<base::FilePath>& ref_segments,
    const std::vector<base::FilePath>& actual_segments,
    const base::FilePath& reference_file,
    const std::string& perf_modifier) {
  ASSERT_GT(ref_segments.size(), 0u)
      << "Failed to split reference file on silence; sox is likely broken.";
  ASSERT_EQ(ref_segments.size(), actual_segments.size())
      << "The recording did not result in the same number of audio segments "
      << "after on splitting on silence; WebRTC must have deformed the audio "
      << "too much.";

  for (size_t i = 0; i < ref_segments.size(); i++) {
    float difference_in_decibel = AnalyzeOneSegment(ref_segments[i],
                                                    actual_segments[i],
                                                    i);
    std::string trace_name = MakeTraceName(reference_file, i);
    perf_test::PrintResult("agc_energy_diff", perf_modifier, trace_name,
                           difference_in_decibel, "dB", false);
  }
}

void ComputeAndPrintPesqResults(const base::FilePath& reference_file,
                                const base::FilePath& recording,
                                const std::string& perf_modifier) {
  base::FilePath trimmed_reference = CreateTemporaryWaveFile();
  base::FilePath trimmed_recording = CreateTemporaryWaveFile();

  ASSERT_TRUE(RemoveSilence(reference_file, trimmed_reference));
  ASSERT_TRUE(RemoveSilence(recording, trimmed_recording));

  std::string raw_mos;
  std::string mos_lqo;
  bool succeeded = RunPesq(trimmed_reference, trimmed_recording, 16000,
                           &raw_mos, &mos_lqo);
  EXPECT_TRUE(succeeded) << "Failed to run PESQ.";
  if (succeeded) {
    perf_test::PrintResult(
        "audio_pesq", perf_modifier, "raw_mos", raw_mos, "score", true);
    perf_test::PrintResult(
        "audio_pesq", perf_modifier, "mos_lqo", mos_lqo, "score", true);
  }

  DeleteFileUnlessTestFailed(trimmed_reference, false);
  DeleteFileUnlessTestFailed(trimmed_recording, false);
}

}  // namespace

// Sets up a two-way WebRTC call and records its output to |recording|, using
// getUserMedia.
//
// |reference_file| should have at least five seconds of silence in the
// beginning: otherwise all the reference audio will not be picked up by the
// recording. Note that the reference file will start playing as soon as the
// audio device is up following the getUserMedia call in the left tab. The time
// it takes to negotiate a call isn't deterministic, but five seconds should be
// plenty of time. Similarly, the recording time should be enough to catch the
// whole reference file. If you then silence-trim the reference file and actual
// file, you should end up with two time-synchronized files.
void MAYBE_WebRtcAudioQualityBrowserTest::SetupAndRecordAudioCall(
    const base::FilePath& reference_file,
    const base::FilePath& recording,
    const std::string& constraints,
    const base::TimeDelta recording_time) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
  ASSERT_TRUE(ForceMicrophoneVolumeTo100Percent());

  ConfigureFakeDeviceToPlayFile(reference_file);

  // Create a two-way call. Mute one of the receivers though; that way it will
  // be receiving audio bytes, but we will not be playing out of both elements.
  GURL test_page = embedded_test_server()->GetURL(kWebRtcAudioTestHtmlPage);
  content::WebContents* left_tab =
      OpenPageAndGetUserMediaInNewTabWithConstraints(test_page, constraints);
  SetupPeerconnectionWithLocalStream(left_tab);
  MuteMediaElement("remote-view", left_tab);

  content::WebContents* right_tab =
      OpenPageAndGetUserMediaInNewTabWithConstraints(test_page, constraints);
  SetupPeerconnectionWithLocalStream(right_tab);

  AudioRecorder recorder;
  ASSERT_TRUE(recorder.StartRecording(recording_time, recording));

  NegotiateCall(left_tab, right_tab);

  ASSERT_TRUE(recorder.WaitForRecordingToEnd());
  DVLOG(0) << "Done recording to " << recording.value() << std::endl;

  HangUp(left_tab);
}

void MAYBE_WebRtcAudioQualityBrowserTest::TestWithFakeDeviceGetUserMedia(
    const std::string& constraints,
    const std::string& perf_modifier) {
  if (OnWin8()) {
    // http://crbug.com/379798.
    LOG(ERROR) << "This test is not implemented for Windows XP/Win8.";
    return;
  }

  base::FilePath reference_file =
      test::GetReferenceFilesDir().Append(kReferenceFile);
  base::FilePath recording = CreateTemporaryWaveFile();

  ASSERT_NO_FATAL_FAILURE(SetupAndRecordAudioCall(
      reference_file, recording, constraints,
      base::TimeDelta::FromSeconds(30)));

  ComputeAndPrintPesqResults(reference_file, recording, perf_modifier);
  DeleteFileUnlessTestFailed(recording, false);
}

IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest,
                       MANUAL_TestCallQualityWithAudioFromFakeDevice) {
  TestWithFakeDeviceGetUserMedia(kAudioOnlyCallConstraints, "_getusermedia");
}

IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest,
                       MANUAL_TestCallQualityWithAudioFromWebAudio) {
  if (OnWin8()) {
    // http://crbug.com/379798.
    LOG(ERROR) << "This test is not implemented for Windows XP/Win8.";
    return;
  }
  ASSERT_TRUE(test::HasReferenceFilesInCheckout());
  ASSERT_TRUE(embedded_test_server()->Start());

  ASSERT_TRUE(ForceMicrophoneVolumeTo100Percent());

  content::WebContents* left_tab =
      OpenPageWithoutGetUserMedia(kWebRtcAudioTestHtmlPage);
  content::WebContents* right_tab =
      OpenPageWithoutGetUserMedia(kWebRtcAudioTestHtmlPage);

  AddAudioFileToWebAudio(kReferenceFileRelativeUrl, left_tab);

  NegotiateCall(left_tab, right_tab);

  base::FilePath recording = CreateTemporaryWaveFile();

  // Note: the sound clip is 21.6 seconds: record for 25 seconds to get some
  // safety margins on each side.
  AudioRecorder recorder;
  ASSERT_TRUE(recorder.StartRecording(base::TimeDelta::FromSeconds(25),
                                      recording));

  PlayAudioFileThroughWebAudio(left_tab);

  ASSERT_TRUE(recorder.WaitForRecordingToEnd());
  DVLOG(0) << "Done recording to " << recording.value() << std::endl;

  HangUp(left_tab);

  // Compare with the reference file on disk (this is the same file we played
  // through WebAudio earlier).
  base::FilePath reference_file =
      test::GetReferenceFilesDir().Append(kReferenceFile);
  ComputeAndPrintPesqResults(reference_file, recording, "_webaudio");
}

/**
 * The auto gain control test plays a file into the fake microphone. Then it
 * sets up a one-way WebRTC call with audio only and records Chrome's output on
 * the receiving side using the audio loopback provided by the quality test
 * (see the class comments for more details).
 *
 * Then both the recording and reference file are split on silence. This creates
 * a number of segments with speech in them. The reason for this is to provide
 * a kind of synchronization mechanism so the start of each speech segment is
 * compared to the start of the corresponding speech segment. This is because we
 * will experience inevitable clock drift between the system clock (which runs
 * the fake microphone) and the sound card (which runs play-out). Effectively
 * re-synchronizing on each segment mitigates this.
 *
 * The silence splitting is inherently sensitive to the sound file we run on.
 * Therefore the reference file must have at least 500 ms of pure silence
 * between speech segments; the test will fail if the output produces more
 * segments than the reference.
 *
 * The test reports the difference in decibel between the reference and output
 * file per 10 ms interval in each speech segment. A value of 6 means the
 * output was 6 dB louder than the reference, presumably because the AGC applied
 * gain to the signal.
 *
 * The test only exercises digital AGC for now.
 *
 * We record in CD format here (44.1 kHz) because that's what the fake input
 * device currently supports, and we want to be able to compare directly. See
 * http://crbug.com/421054.
 */
void MAYBE_WebRtcAudioQualityBrowserTest::TestAutoGainControl(
    const base::FilePath::StringType& reference_filename,
    const std::string& constraints,
    const std::string& perf_modifier) {
  if (OnWin8()) {
    // http://crbug.com/379798.
    LOG(ERROR) << "This test is not implemented for Windows XP/Win8.";
    return;
  }
  base::FilePath reference_file =
      test::GetReferenceFilesDir().Append(reference_filename);
  base::FilePath recording = CreateTemporaryWaveFile();

  ASSERT_NO_FATAL_FAILURE(SetupAndRecordAudioCall(
      reference_file, recording, constraints,
      base::TimeDelta::FromSeconds(30)));

  base::ScopedTempDir split_ref_files;
  ASSERT_TRUE(split_ref_files.CreateUniqueTempDir());
  ASSERT_NO_FATAL_FAILURE(
      SplitFileOnSilenceIntoDir(reference_file, split_ref_files.path()));
  std::vector<base::FilePath> ref_segments =
      ListWavFilesInDir(split_ref_files.path());

  base::ScopedTempDir split_actual_files;
  ASSERT_TRUE(split_actual_files.CreateUniqueTempDir());
  ASSERT_NO_FATAL_FAILURE(
      SplitFileOnSilenceIntoDir(recording, split_actual_files.path()));

  // Keep the recording and split files if the analysis fails.
  base::FilePath actual_files_dir = split_actual_files.Take();
  std::vector<base::FilePath> actual_segments =
      ListWavFilesInDir(actual_files_dir);

  AnalyzeSegmentsAndPrintResult(
      ref_segments, actual_segments, reference_file, perf_modifier);

  DeleteFileUnlessTestFailed(recording, false);
  DeleteFileUnlessTestFailed(actual_files_dir, true);
}

// The AGC should apply non-zero gain here.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest,
                       MANUAL_TestAutoGainControlOnLowAudio) {
  ASSERT_NO_FATAL_FAILURE(TestAutoGainControl(
      kReferenceFile, kAudioOnlyCallConstraints, "_with_agc"));
}

// Since the AGC is off here there should be no gain at all.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAudioQualityBrowserTest,
                       MANUAL_TestAutoGainIsOffWithAudioProcessingOff) {
  const char* kAudioCallWithoutAudioProcessing =
      "{audio: { mandatory: { echoCancellation: false } } }";
  ASSERT_NO_FATAL_FAILURE(TestAutoGainControl(
      kReferenceFile, kAudioCallWithoutAudioProcessing, "_no_agc"));
}
