diff --git a/modules/audio_device/include/test_audio_device.cc b/modules/audio_device/include/test_audio_device.cc index 7d55c47529..7d18d825a1 100644 --- a/modules/audio_device/include/test_audio_device.cc +++ b/modules/audio_device/include/test_audio_device.cc @@ -22,20 +22,20 @@ #include "rtc_base/checks.h" #include "rtc_base/criticalsection.h" #include "rtc_base/event.h" -#include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/platform_thread.h" #include "rtc_base/random.h" #include "rtc_base/refcountedobject.h" -#include "rtc_base/thread.h" -#include "rtc_base/timeutils.h" +#include "system_wrappers/include/event_wrapper.h" namespace webrtc { +class EventTimerWrapper; + namespace { -constexpr int kFrameLengthUs = 10000; -constexpr int kFramesPerSecond = rtc::kNumMicrosecsPerSec / kFrameLengthUs; +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. @@ -54,13 +54,13 @@ class TestAudioDeviceModuleImpl float speed = 1) : capturer_(std::move(capturer)), renderer_(std::move(renderer)), - process_interval_us_(kFrameLengthUs / speed), + speed_(speed), audio_callback_(nullptr), rendering_(false), capturing_(false), done_rendering_(true, true), done_capturing_(true, true), - stop_thread_(false) { + tick_(EventTimerWrapper::Create()) { auto good_sample_rate = [](int sr) { return sr == 8000 || sr == 16000 || sr == 32000 || sr == 44100 || sr == 48000; @@ -81,19 +81,16 @@ class TestAudioDeviceModuleImpl StopPlayout(); StopRecording(); if (thread_) { - { - rtc::CritScope cs(&lock_); - stop_thread_ = true; - } thread_->Stop(); } } int32_t Init() { + RTC_CHECK(tick_->StartTimer(true, kFrameLengthMs / speed_)); thread_ = absl::make_unique( - TestAudioDeviceModuleImpl::Run, this, "TestAudioDeviceModuleImpl", - rtc::kHighPriority); + TestAudioDeviceModuleImpl::Run, this, "TestAudioDeviceModuleImpl"); thread_->Start(); + thread_->SetPriority(rtc::kHighPriority); return 0; } @@ -158,72 +155,51 @@ class TestAudioDeviceModuleImpl private: void ProcessAudio() { - int64_t time_us = rtc::TimeMicros(); - bool logged_once = false; - for (;;) { - { - rtc::CritScope cs(&lock_); - if (stop_thread_) { - return; + { + 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 = 0; + 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 (capturing_) { - // Capture 10ms of audio. 2 bytes per sample. - const bool keep_capturing = capturer_->Capture(&recording_buffer_); - uint32_t new_mic_level = 0; - 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 = 0; - int64_t elapsed_time_ms = -1; - int64_t ntp_time_ms = -1; - 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(); - } + if (!keep_capturing) { + capturing_ = false; + done_capturing_.Set(); } } - time_us += process_interval_us_; - - int64_t time_left_us = time_us - rtc::TimeMicros(); - if (time_left_us < 0) { - if (!logged_once) { - RTC_LOG(LS_ERROR) << "ProcessAudio is too slow"; - logged_once = true; - } - } else { - while (time_left_us > 1000) { - if (rtc::Thread::SleepMs(time_left_us / 1000)) - break; - time_left_us = time_us - rtc::TimeMicros(); + if (rendering_) { + size_t samples_out = 0; + int64_t elapsed_time_ms = -1; + int64_t ntp_time_ms = -1; + 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 void Run(void* obj) { + 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 int64_t process_interval_us_; + const float speed_; rtc::CriticalSection lock_; AudioTransport* audio_callback_ RTC_GUARDED_BY(lock_); @@ -235,8 +211,8 @@ class TestAudioDeviceModuleImpl std::vector playout_buffer_ RTC_GUARDED_BY(lock_); rtc::BufferT recording_buffer_ RTC_GUARDED_BY(lock_); + std::unique_ptr tick_; std::unique_ptr thread_; - bool stop_thread_ RTC_GUARDED_BY(lock_); }; // A fake capturer that generates pulses with random samples between