diff --git a/modules/audio_device/BUILD.gn b/modules/audio_device/BUILD.gn index be53d36452..211117608d 100644 --- a/modules/audio_device/BUILD.gn +++ b/modules/audio_device/BUILD.gn @@ -133,9 +133,8 @@ rtc_source_set("audio_device_generic") { "include/audio_device_default.h", "include/audio_device_defines.h", "include/fake_audio_device.h", + "include/test_audio_device.cc", "include/test_audio_device.h", - "include/test_audio_device_impl.cc", - "include/test_audio_device_impl.h", ] if (build_with_mozilla) { @@ -344,7 +343,7 @@ if (rtc_include_tests) { sources = [ "fine_audio_buffer_unittest.cc", - "include/test_audio_device_impl_unittest.cc", + "include/test_audio_device_unittest.cc", ] deps = [ ":audio_device", diff --git a/modules/audio_device/include/test_audio_device_impl.cc b/modules/audio_device/include/test_audio_device.cc similarity index 66% rename from modules/audio_device/include/test_audio_device_impl.cc rename to modules/audio_device/include/test_audio_device.cc index 002fca7f65..f888cd0838 100644 --- a/modules/audio_device/include/test_audio_device_impl.cc +++ b/modules/audio_device/include/test_audio_device.cc @@ -7,8 +7,6 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_device/include/test_audio_device_impl.h" - #include #include #include @@ -33,165 +31,188 @@ namespace webrtc { class EventTimerWrapper; -// todo(titovartem): use anonymous namespace here after downstream projects -// won't use test/FakeAudioDevice -namespace webrtc_impl { +namespace { constexpr int kFrameLengthMs = 10; constexpr int kFramesPerSecond = 1000 / kFrameLengthMs; // TestAudioDeviceModule implements an AudioDevice module that can act both as a // capturer and a renderer. It will use 10ms audio frames. -TestAudioDeviceModuleImpl::TestAudioDeviceModuleImpl( - std::unique_ptr capturer, - std::unique_ptr renderer, - float speed) - : capturer_(std::move(capturer)), - renderer_(std::move(renderer)), - speed_(speed), - audio_callback_(nullptr), - rendering_(false), - capturing_(false), - done_rendering_(true, true), - done_capturing_(true, true), - tick_(EventTimerWrapper::Create()), - thread_(TestAudioDeviceModuleImpl::Run, - this, - "TestAudioDeviceModuleImpl") { - auto good_sample_rate = [](int sr) { - return sr == 8000 || sr == 16000 || sr == 32000 || sr == 44100 || - sr == 48000; - }; +class TestAudioDeviceModuleImpl + : public webrtc_impl::AudioDeviceModuleDefault { + public: + // Creates a new TestAudioDeviceModule. When capturing or playing, 10 ms audio + // frames will be processed every 10ms / |speed|. + // |capturer| is an object that produces audio data. Can be nullptr if this + // device is never used for recording. + // |renderer| is an object that receives audio data that would have been + // played out. Can be nullptr if this device is never used for playing. + // Use one of the Create... functions to get these instances. + TestAudioDeviceModuleImpl(std::unique_ptr capturer, + std::unique_ptr renderer, + float speed = 1) + : capturer_(std::move(capturer)), + renderer_(std::move(renderer)), + speed_(speed), + audio_callback_(nullptr), + rendering_(false), + capturing_(false), + done_rendering_(true, true), + done_capturing_(true, true), + tick_(EventTimerWrapper::Create()), + thread_(TestAudioDeviceModuleImpl::Run, + this, + "TestAudioDeviceModuleImpl") { + auto good_sample_rate = [](int sr) { + return sr == 8000 || sr == 16000 || sr == 32000 || sr == 44100 || + sr == 48000; + }; - if (renderer_) { - const int sample_rate = renderer_->SamplingFrequency(); - playout_buffer_.resize( - SamplesPerFrame(sample_rate) * renderer_->NumChannels(), 0); - RTC_CHECK(good_sample_rate(sample_rate)); + if (renderer_) { + const int sample_rate = renderer_->SamplingFrequency(); + playout_buffer_.resize( + SamplesPerFrame(sample_rate) * renderer_->NumChannels(), 0); + RTC_CHECK(good_sample_rate(sample_rate)); + } + if (capturer_) { + RTC_CHECK(good_sample_rate(capturer_->SamplingFrequency())); + } } - if (capturer_) { - RTC_CHECK(good_sample_rate(capturer_->SamplingFrequency())); + + ~TestAudioDeviceModuleImpl() { + StopPlayout(); + StopRecording(); + thread_.Stop(); } -} -TestAudioDeviceModuleImpl::~TestAudioDeviceModuleImpl() { - StopPlayout(); - StopRecording(); - thread_.Stop(); -} + int32_t Init() { + RTC_CHECK(tick_->StartTimer(true, kFrameLengthMs / speed_)); + thread_.Start(); + thread_.SetPriority(rtc::kHighPriority); + return 0; + } -int32_t TestAudioDeviceModuleImpl::Init() { - RTC_CHECK(tick_->StartTimer(true, kFrameLengthMs / speed_)); - thread_.Start(); - thread_.SetPriority(rtc::kHighPriority); - return 0; -} - -int32_t TestAudioDeviceModuleImpl::RegisterAudioCallback( - AudioTransport* callback) { - rtc::CritScope cs(&lock_); - RTC_DCHECK(callback || audio_callback_); - audio_callback_ = callback; - return 0; -} - -int32_t TestAudioDeviceModuleImpl::StartPlayout() { - rtc::CritScope cs(&lock_); - RTC_CHECK(renderer_); - rendering_ = true; - done_rendering_.Reset(); - return 0; -} - -int32_t TestAudioDeviceModuleImpl::StopPlayout() { - rtc::CritScope cs(&lock_); - rendering_ = false; - done_rendering_.Set(); - return 0; -} - -int32_t TestAudioDeviceModuleImpl::StartRecording() { - rtc::CritScope cs(&lock_); - RTC_CHECK(capturer_); - capturing_ = true; - done_capturing_.Reset(); - return 0; -} - -int32_t TestAudioDeviceModuleImpl::StopRecording() { - rtc::CritScope cs(&lock_); - capturing_ = false; - done_capturing_.Set(); - return 0; -} - -bool TestAudioDeviceModuleImpl::Playing() const { - rtc::CritScope cs(&lock_); - return rendering_; -} - -bool TestAudioDeviceModuleImpl::Recording() const { - rtc::CritScope cs(&lock_); - return capturing_; -} - -// Blocks until the Renderer refuses to receive data. -// Returns false if |timeout_ms| passes before that happens. -bool TestAudioDeviceModuleImpl::WaitForPlayoutEnd(int timeout_ms) { - return done_rendering_.Wait(timeout_ms); -} -// Blocks until the Recorder stops producing data. -// Returns false if |timeout_ms| passes before that happens. -bool TestAudioDeviceModuleImpl::WaitForRecordingEnd(int timeout_ms) { - return done_capturing_.Wait(timeout_ms); -} - -void TestAudioDeviceModuleImpl::ProcessAudio() { - { + int32_t RegisterAudioCallback(AudioTransport* callback) { rtc::CritScope cs(&lock_); - if (capturing_) { - // Capture 10ms of audio. 2 bytes per sample. - const bool keep_capturing = capturer_->Capture(&recording_buffer_); - uint32_t new_mic_level; - if (recording_buffer_.size() > 0) { - audio_callback_->RecordedDataIsAvailable( - recording_buffer_.data(), recording_buffer_.size(), 2, - capturer_->NumChannels(), capturer_->SamplingFrequency(), 0, 0, 0, - false, new_mic_level); - } - if (!keep_capturing) { - capturing_ = false; - done_capturing_.Set(); - } - } - if (rendering_) { - size_t samples_out; - int64_t elapsed_time_ms; - int64_t ntp_time_ms; - const int sampling_frequency = renderer_->SamplingFrequency(); - audio_callback_->NeedMorePlayData( - SamplesPerFrame(sampling_frequency), 2, renderer_->NumChannels(), - sampling_frequency, playout_buffer_.data(), samples_out, - &elapsed_time_ms, &ntp_time_ms); - const bool keep_rendering = renderer_->Render( - rtc::ArrayView(playout_buffer_.data(), samples_out)); - if (!keep_rendering) { - rendering_ = false; - done_rendering_.Set(); - } - } + RTC_DCHECK(callback || audio_callback_); + audio_callback_ = callback; + return 0; } - tick_->Wait(WEBRTC_EVENT_INFINITE); -} -bool TestAudioDeviceModuleImpl::Run(void* obj) { - static_cast(obj)->ProcessAudio(); - return true; -} + int32_t StartPlayout() { + rtc::CritScope cs(&lock_); + RTC_CHECK(renderer_); + rendering_ = true; + done_rendering_.Reset(); + return 0; + } -} // namespace webrtc_impl + int32_t StopPlayout() { + rtc::CritScope cs(&lock_); + rendering_ = false; + done_rendering_.Set(); + return 0; + } + + int32_t StartRecording() { + rtc::CritScope cs(&lock_); + RTC_CHECK(capturer_); + capturing_ = true; + done_capturing_.Reset(); + return 0; + } + + int32_t StopRecording() { + rtc::CritScope cs(&lock_); + capturing_ = false; + done_capturing_.Set(); + return 0; + } + + bool Playing() const { + rtc::CritScope cs(&lock_); + return rendering_; + } + + bool Recording() const { + rtc::CritScope cs(&lock_); + return capturing_; + } + + // Blocks until the Renderer refuses to receive data. + // Returns false if |timeout_ms| passes before that happens. + bool WaitForPlayoutEnd(int timeout_ms = rtc::Event::kForever) { + return done_rendering_.Wait(timeout_ms); + } + + // Blocks until the Recorder stops producing data. + // Returns false if |timeout_ms| passes before that happens. + bool WaitForRecordingEnd(int timeout_ms = rtc::Event::kForever) { + return done_capturing_.Wait(timeout_ms); + } + + private: + void ProcessAudio() { + { + rtc::CritScope cs(&lock_); + if (capturing_) { + // Capture 10ms of audio. 2 bytes per sample. + const bool keep_capturing = capturer_->Capture(&recording_buffer_); + uint32_t new_mic_level; + if (recording_buffer_.size() > 0) { + audio_callback_->RecordedDataIsAvailable( + recording_buffer_.data(), recording_buffer_.size(), 2, + capturer_->NumChannels(), capturer_->SamplingFrequency(), 0, 0, 0, + false, new_mic_level); + } + if (!keep_capturing) { + capturing_ = false; + done_capturing_.Set(); + } + } + if (rendering_) { + size_t samples_out; + int64_t elapsed_time_ms; + int64_t ntp_time_ms; + const int sampling_frequency = renderer_->SamplingFrequency(); + audio_callback_->NeedMorePlayData( + SamplesPerFrame(sampling_frequency), 2, renderer_->NumChannels(), + sampling_frequency, playout_buffer_.data(), samples_out, + &elapsed_time_ms, &ntp_time_ms); + const bool keep_rendering = renderer_->Render( + rtc::ArrayView(playout_buffer_.data(), samples_out)); + if (!keep_rendering) { + rendering_ = false; + done_rendering_.Set(); + } + } + } + tick_->Wait(WEBRTC_EVENT_INFINITE); + } + + static bool Run(void* obj) { + static_cast(obj)->ProcessAudio(); + return true; + } + + const std::unique_ptr capturer_ RTC_GUARDED_BY(lock_); + const std::unique_ptr renderer_ RTC_GUARDED_BY(lock_); + const float speed_; + + rtc::CriticalSection lock_; + AudioTransport* audio_callback_ RTC_GUARDED_BY(lock_); + bool rendering_ RTC_GUARDED_BY(lock_); + bool capturing_ RTC_GUARDED_BY(lock_); + rtc::Event done_rendering_; + rtc::Event done_capturing_; + + std::vector playout_buffer_ RTC_GUARDED_BY(lock_); + rtc::BufferT recording_buffer_ RTC_GUARDED_BY(lock_); + + std::unique_ptr tick_; + rtc::PlatformThread thread_; +}; -namespace { // A fake capturer that generates pulses with random samples between // -max_amplitude and +max_amplitude. class PulsedNoiseCapturerImpl final @@ -264,9 +285,7 @@ class WavFileReader final : public TestAudioDeviceModule::Capturer { int SamplingFrequency() const override { return sampling_frequency_in_hz_; } - int NumChannels() const override { - return num_channels_; - } + int NumChannels() const override { return num_channels_; } bool Capture(rtc::BufferT* buffer) override { buffer->SetData( @@ -286,18 +305,16 @@ class WavFileReader final : public TestAudioDeviceModule::Capturer { class WavFileWriter final : public TestAudioDeviceModule::Renderer { public: - WavFileWriter(std::string filename, int sampling_frequency_in_hz, + WavFileWriter(std::string filename, + int sampling_frequency_in_hz, int num_channels) : sampling_frequency_in_hz_(sampling_frequency_in_hz), - wav_writer_(filename, sampling_frequency_in_hz, - num_channels), + wav_writer_(filename, sampling_frequency_in_hz, num_channels), num_channels_(num_channels) {} int SamplingFrequency() const override { return sampling_frequency_in_hz_; } - int NumChannels() const override { - return num_channels_; - } + int NumChannels() const override { return num_channels_; } bool Render(rtc::ArrayView data) override { wav_writer_.WriteSamples(data.data(), data.size()); @@ -327,9 +344,7 @@ class BoundedWavFileWriter : public TestAudioDeviceModule::Renderer { int SamplingFrequency() const override { return sampling_frequency_in_hz_; } - int NumChannels() const override { - return num_channels_; - } + int NumChannels() const override { return num_channels_; } bool Render(rtc::ArrayView data) override { const int16_t kAmplitudeThreshold = 5; @@ -388,13 +403,9 @@ class DiscardRenderer final : public TestAudioDeviceModule::Renderer { int SamplingFrequency() const override { return sampling_frequency_in_hz_; } - int NumChannels() const override { - return num_channels_; - } + int NumChannels() const override { return num_channels_; } - bool Render(rtc::ArrayView data) override { - return true; - } + bool Render(rtc::ArrayView data) override { return true; } private: int sampling_frequency_in_hz_; @@ -404,8 +415,7 @@ class DiscardRenderer final : public TestAudioDeviceModule::Renderer { } // namespace size_t TestAudioDeviceModule::SamplesPerFrame(int sampling_frequency_in_hz) { - return rtc::CheckedDivExact(sampling_frequency_in_hz, - webrtc_impl::kFramesPerSecond); + return rtc::CheckedDivExact(sampling_frequency_in_hz, kFramesPerSecond); } rtc::scoped_refptr @@ -413,7 +423,7 @@ TestAudioDeviceModule::CreateTestAudioDeviceModule( std::unique_ptr capturer, std::unique_ptr renderer, float speed) { - return new rtc::RefCountedObject( + return new rtc::RefCountedObject( std::move(capturer), std::move(renderer), speed); } diff --git a/modules/audio_device/include/test_audio_device_impl.h b/modules/audio_device/include/test_audio_device_impl.h deleted file mode 100644 index f570073151..0000000000 --- a/modules/audio_device/include/test_audio_device_impl.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2018 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 MODULES_AUDIO_DEVICE_INCLUDE_TEST_AUDIO_DEVICE_IMPL_H_ -#define MODULES_AUDIO_DEVICE_INCLUDE_TEST_AUDIO_DEVICE_IMPL_H_ - -#include -#include -#include - -#include "modules/audio_device/include/audio_device_default.h" -#include "modules/audio_device/include/test_audio_device.h" -#include "rtc_base/buffer.h" -#include "rtc_base/criticalsection.h" -#include "rtc_base/event.h" -#include "rtc_base/platform_thread.h" - -namespace webrtc { - -class EventTimerWrapper; - -namespace webrtc_impl { - -// TestAudioDeviceModule implements an AudioDevice module that can act both as a -// capturer and a renderer. It will use 10ms audio frames. -// todo(titovartem): hide implementation after downstream projects won't use -// test/FakeAudioDevice -class TestAudioDeviceModuleImpl - : public AudioDeviceModuleDefault { - public: - // Creates a new TestAudioDeviceModule. When capturing or playing, 10 ms audio - // frames will be processed every 10ms / |speed|. - // |capturer| is an object that produces audio data. Can be nullptr if this - // device is never used for recording. - // |renderer| is an object that receives audio data that would have been - // played out. Can be nullptr if this device is never used for playing. - // Use one of the Create... functions to get these instances. - TestAudioDeviceModuleImpl(std::unique_ptr capturer, - std::unique_ptr renderer, - float speed = 1); - - ~TestAudioDeviceModuleImpl() override; - - int32_t Init() override; - int32_t RegisterAudioCallback(AudioTransport* callback) override; - int32_t StartPlayout() override; - int32_t StopPlayout() override; - int32_t StartRecording() override; - int32_t StopRecording() override; - bool Playing() const override; - bool Recording() const override; - - // Blocks until the Renderer refuses to receive data. - // Returns false if |timeout_ms| passes before that happens. - bool WaitForPlayoutEnd(int timeout_ms = rtc::Event::kForever) override; - // Blocks until the Recorder stops producing data. - // Returns false if |timeout_ms| passes before that happens. - bool WaitForRecordingEnd(int timeout_ms = rtc::Event::kForever) override; - - private: - void ProcessAudio(); - static bool Run(void* obj); - - const std::unique_ptr capturer_ RTC_GUARDED_BY(lock_); - const std::unique_ptr renderer_ RTC_GUARDED_BY(lock_); - const float speed_; - - rtc::CriticalSection lock_; - AudioTransport* audio_callback_ RTC_GUARDED_BY(lock_); - bool rendering_ RTC_GUARDED_BY(lock_); - bool capturing_ RTC_GUARDED_BY(lock_); - rtc::Event done_rendering_; - rtc::Event done_capturing_; - - std::vector playout_buffer_ RTC_GUARDED_BY(lock_); - rtc::BufferT recording_buffer_ RTC_GUARDED_BY(lock_); - - std::unique_ptr tick_; - rtc::PlatformThread thread_; -}; - -} // namespace webrtc_impl -} // namespace webrtc - -#endif // MODULES_AUDIO_DEVICE_INCLUDE_TEST_AUDIO_DEVICE_IMPL_H_ diff --git a/modules/audio_device/include/test_audio_device_impl_unittest.cc b/modules/audio_device/include/test_audio_device_unittest.cc similarity index 100% rename from modules/audio_device/include/test_audio_device_impl_unittest.cc rename to modules/audio_device/include/test_audio_device_unittest.cc