Introduce CopyToFileAudioCapturer.

It will be used to dump generated audio from TestAudioDeviceModule into
user defuned file in peer connection level test framework.

Bug: webrtc:10138
Change-Id: I6e3db36aaf1303ab148e8812937c4f9cd1b49315
Reviewed-on: https://webrtc-review.googlesource.com/c/117220
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26267}
diff --git a/modules/audio_device/include/test_audio_device.h b/modules/audio_device/include/test_audio_device.h
index 93f0b13..6fe1c1a 100644
--- a/modules/audio_device/include/test_audio_device.h
+++ b/modules/audio_device/include/test_audio_device.h
@@ -64,12 +64,12 @@
   // -max_amplitude and +max_amplitude.
   class PulsedNoiseCapturer : public Capturer {
    public:
-    virtual ~PulsedNoiseCapturer() {}
+    ~PulsedNoiseCapturer() override {}
 
     virtual void SetMaxAmplitude(int16_t amplitude) = 0;
   };
 
-  virtual ~TestAudioDeviceModule() {}
+  ~TestAudioDeviceModule() override {}
 
   // Creates a new TestAudioDeviceModule. When capturing or playing, 10 ms audio
   // frames will be processed every 10ms / |speed|.
@@ -150,16 +150,16 @@
       int sampling_frequency_in_hz,
       int num_channels = 1);
 
-  virtual int32_t Init() = 0;
-  virtual int32_t RegisterAudioCallback(AudioTransport* callback) = 0;
+  int32_t Init() override = 0;
+  int32_t RegisterAudioCallback(AudioTransport* callback) override = 0;
 
-  virtual int32_t StartPlayout() = 0;
-  virtual int32_t StopPlayout() = 0;
-  virtual int32_t StartRecording() = 0;
-  virtual int32_t StopRecording() = 0;
+  int32_t StartPlayout() override = 0;
+  int32_t StopPlayout() override = 0;
+  int32_t StartRecording() override = 0;
+  int32_t StopRecording() override = 0;
 
-  virtual bool Playing() const = 0;
-  virtual bool Recording() const = 0;
+  bool Playing() const override = 0;
+  bool Recording() const override = 0;
 
   // Blocks until the Renderer refuses to receive data.
   // Returns false if |timeout_ms| passes before that happens.
diff --git a/test/BUILD.gn b/test/BUILD.gn
index a21637f..25bd539 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -16,6 +16,7 @@
   testonly = true
 
   deps = [
+    ":copy_to_file_audio_capturer",
     ":rtp_test_utils",
     ":test_common",
     ":test_renderer",
@@ -328,6 +329,7 @@
   rtc_test("test_support_unittests") {
     deps = [
       ":call_config_utils",
+      ":copy_to_file_audio_capturer_unittest",
       ":direct_transport",
       ":fake_video_codecs",
       ":fileutils",
@@ -864,6 +866,36 @@
   ]
 }
 
+rtc_source_set("copy_to_file_audio_capturer") {
+  testonly = true
+  sources = [
+    "testsupport/copy_to_file_audio_capturer.cc",
+    "testsupport/copy_to_file_audio_capturer.h",
+  ]
+  deps = [
+    "../api:array_view",
+    "../common_audio:common_audio",
+    "../modules/audio_device:audio_device_impl",
+    "../rtc_base:rtc_base_approved",
+    "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
+
+rtc_source_set("copy_to_file_audio_capturer_unittest") {
+  testonly = true
+  sources = [
+    "testsupport/copy_to_file_audio_capturer_unittest.cc",
+  ]
+  deps = [
+    ":copy_to_file_audio_capturer",
+    ":fileutils",
+    ":test_support",
+    "../modules/audio_device:audio_device_impl",
+    "//third_party/abseil-cpp/absl/memory",
+  ]
+}
+
 if (!build_with_chromium && is_android) {
   rtc_android_library("native_test_java") {
     testonly = true
diff --git a/test/testsupport/copy_to_file_audio_capturer.cc b/test/testsupport/copy_to_file_audio_capturer.cc
new file mode 100644
index 0000000..3c19da4
--- /dev/null
+++ b/test/testsupport/copy_to_file_audio_capturer.cc
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2019 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 "test/testsupport/copy_to_file_audio_capturer.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+namespace test {
+
+CopyToFileAudioCapturer::CopyToFileAudioCapturer(
+    std::unique_ptr<TestAudioDeviceModule::Capturer> delegate,
+    std::string stream_dump_file_name)
+    : delegate_(std::move(delegate)),
+      wav_writer_(absl::make_unique<WavWriter>(std::move(stream_dump_file_name),
+                                               delegate_->SamplingFrequency(),
+                                               delegate_->NumChannels())) {}
+CopyToFileAudioCapturer::~CopyToFileAudioCapturer() = default;
+
+int CopyToFileAudioCapturer::SamplingFrequency() const {
+  return delegate_->SamplingFrequency();
+}
+
+int CopyToFileAudioCapturer::NumChannels() const {
+  return delegate_->NumChannels();
+}
+
+bool CopyToFileAudioCapturer::Capture(rtc::BufferT<int16_t>* buffer) {
+  bool result = delegate_->Capture(buffer);
+  if (result) {
+    wav_writer_->WriteSamples(buffer->data(), buffer->size());
+  }
+  return result;
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/test/testsupport/copy_to_file_audio_capturer.h b/test/testsupport/copy_to_file_audio_capturer.h
new file mode 100644
index 0000000..a410bee
--- /dev/null
+++ b/test/testsupport/copy_to_file_audio_capturer.h
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2019 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.
+ */
+
+#ifndef TEST_TESTSUPPORT_COPY_TO_FILE_AUDIO_CAPTURER_H_
+#define TEST_TESTSUPPORT_COPY_TO_FILE_AUDIO_CAPTURER_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "common_audio/wav_file.h"
+#include "modules/audio_device/include/test_audio_device.h"
+#include "rtc_base/buffer.h"
+
+namespace webrtc {
+namespace test {
+
+// TestAudioDeviceModule::Capturer that will store audio data, captured by
+// delegate to the specified output file. Can be used to create a copy of
+// generated audio data to be able then to compare it as a reference with
+// audio on the TestAudioDeviceModule::Renderer side.
+class CopyToFileAudioCapturer : public TestAudioDeviceModule::Capturer {
+ public:
+  CopyToFileAudioCapturer(
+      std::unique_ptr<TestAudioDeviceModule::Capturer> delegate,
+      std::string stream_dump_file_name);
+  ~CopyToFileAudioCapturer() override;
+
+  int SamplingFrequency() const override;
+  int NumChannels() const override;
+  bool Capture(rtc::BufferT<int16_t>* buffer) override;
+
+ private:
+  std::unique_ptr<TestAudioDeviceModule::Capturer> delegate_;
+  std::unique_ptr<WavWriter> wav_writer_;
+};
+
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // TEST_TESTSUPPORT_COPY_TO_FILE_AUDIO_CAPTURER_H_
diff --git a/test/testsupport/copy_to_file_audio_capturer_unittest.cc b/test/testsupport/copy_to_file_audio_capturer_unittest.cc
new file mode 100644
index 0000000..13c2d00
--- /dev/null
+++ b/test/testsupport/copy_to_file_audio_capturer_unittest.cc
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (c) 2019 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 "test/testsupport/copy_to_file_audio_capturer.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "modules/audio_device/include/test_audio_device.h"
+#include "test/gtest.h"
+#include "test/testsupport/file_utils.h"
+
+namespace webrtc {
+namespace test {
+
+class CopyToFileAudioCapturerTest : public testing::Test {
+ protected:
+  void SetUp() override {
+    temp_filename_ = webrtc::test::TempFilename(
+        webrtc::test::OutputPath(), "copy_to_file_audio_capturer_unittest");
+    std::unique_ptr<TestAudioDeviceModule::Capturer> delegate =
+        TestAudioDeviceModule::CreatePulsedNoiseCapturer(32000, 48000);
+    capturer_ = absl::make_unique<CopyToFileAudioCapturer>(std::move(delegate),
+                                                           temp_filename_);
+  }
+
+  void TearDown() override { ASSERT_EQ(remove(temp_filename_.c_str()), 0); }
+
+  std::unique_ptr<CopyToFileAudioCapturer> capturer_;
+  std::string temp_filename_;
+};
+
+TEST_F(CopyToFileAudioCapturerTest, Capture) {
+  rtc::BufferT<int16_t> expected_buffer;
+  ASSERT_TRUE(capturer_->Capture(&expected_buffer));
+  ASSERT_TRUE(!expected_buffer.empty());
+  // Destruct capturer to close wav file.
+  capturer_.reset(nullptr);
+
+  // Read resulted file content with |wav_file_capture| and compare with
+  // what was captured.
+  std::unique_ptr<TestAudioDeviceModule::Capturer> wav_file_capturer =
+      TestAudioDeviceModule::CreateWavFileReader(temp_filename_, 48000);
+  rtc::BufferT<int16_t> actual_buffer;
+  wav_file_capturer->Capture(&actual_buffer);
+  ASSERT_EQ(actual_buffer, expected_buffer);
+}
+
+}  // namespace test
+}  // namespace webrtc