From 66a29b9953c0959cc9639f43323befb22fce8ec7 Mon Sep 17 00:00:00 2001 From: Artem Titov Date: Tue, 15 Jan 2019 14:43:20 +0100 Subject: [PATCH] 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 Reviewed-by: Karl Wiberg Reviewed-by: Mirko Bonadei Cr-Commit-Position: refs/heads/master@{#26267} --- .../audio_device/include/test_audio_device.h | 20 +++---- test/BUILD.gn | 32 ++++++++++ .../copy_to_file_audio_capturer.cc | 46 +++++++++++++++ .../testsupport/copy_to_file_audio_capturer.h | 49 ++++++++++++++++ .../copy_to_file_audio_capturer_unittest.cc | 58 +++++++++++++++++++ 5 files changed, 195 insertions(+), 10 deletions(-) create mode 100644 test/testsupport/copy_to_file_audio_capturer.cc create mode 100644 test/testsupport/copy_to_file_audio_capturer.h create mode 100644 test/testsupport/copy_to_file_audio_capturer_unittest.cc diff --git a/modules/audio_device/include/test_audio_device.h b/modules/audio_device/include/test_audio_device.h index 93f0b13601..6fe1c1a801 100644 --- a/modules/audio_device/include/test_audio_device.h +++ b/modules/audio_device/include/test_audio_device.h @@ -64,12 +64,12 @@ class TestAudioDeviceModule : public AudioDeviceModule { // -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 @@ class TestAudioDeviceModule : public AudioDeviceModule { 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 a21637fd7c..25bd539419 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -16,6 +16,7 @@ group("test") { testonly = true deps = [ + ":copy_to_file_audio_capturer", ":rtp_test_utils", ":test_common", ":test_renderer", @@ -328,6 +329,7 @@ if (rtc_include_tests) { 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("audio_codec_mocks") { ] } +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 0000000000..3c19da466a --- /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 + +#include "absl/memory/memory.h" + +namespace webrtc { +namespace test { + +CopyToFileAudioCapturer::CopyToFileAudioCapturer( + std::unique_ptr delegate, + std::string stream_dump_file_name) + : delegate_(std::move(delegate)), + wav_writer_(absl::make_unique(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* 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 0000000000..a410beeea8 --- /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 +#include + +#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 delegate, + std::string stream_dump_file_name); + ~CopyToFileAudioCapturer() override; + + int SamplingFrequency() const override; + int NumChannels() const override; + bool Capture(rtc::BufferT* buffer) override; + + private: + std::unique_ptr delegate_; + std::unique_ptr 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 0000000000..13c2d009e8 --- /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 +#include + +#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 delegate = + TestAudioDeviceModule::CreatePulsedNoiseCapturer(32000, 48000); + capturer_ = absl::make_unique(std::move(delegate), + temp_filename_); + } + + void TearDown() override { ASSERT_EQ(remove(temp_filename_.c_str()), 0); } + + std::unique_ptr capturer_; + std::string temp_filename_; +}; + +TEST_F(CopyToFileAudioCapturerTest, Capture) { + rtc::BufferT 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 wav_file_capturer = + TestAudioDeviceModule::CreateWavFileReader(temp_filename_, 48000); + rtc::BufferT actual_buffer; + wav_file_capturer->Capture(&actual_buffer); + ASSERT_EQ(actual_buffer, expected_buffer); +} + +} // namespace test +} // namespace webrtc