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