Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1289)

Unified Diff: webrtc/test/file_audio_device.cc

Issue 2717623003: Add the ability to read/write to WAV files in FakeAudioDevice (Closed)
Patch Set: Don't run the thread all the time; add more checks Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« webrtc/test/file_audio_device.h ('K') | « webrtc/test/file_audio_device.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/test/file_audio_device.cc
diff --git a/webrtc/test/file_audio_device.cc b/webrtc/test/file_audio_device.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5c8fb37845a94aa53bf88a8f9cc4fa17ea4dc319
--- /dev/null
+++ b/webrtc/test/file_audio_device.cc
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2017 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 "webrtc/test/file_audio_device.h"
+
+#include <algorithm>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/system_wrappers/include/event_wrapper.h"
+
+namespace webrtc {
+
+namespace {
+
+constexpr int kFrameLengthMs = 10;
+constexpr int kFramesPerSecond = 1000 / kFrameLengthMs;
+
+int NumSamplesPerFrame(int sample_rate_hz) {
+ return rtc::CheckedDivExact(sample_rate_hz, kFramesPerSecond);
+}
+
+} // namespace
+namespace test {
+
+FileReaderAudioDevice::FileReaderAudioDevice(std::string filename, float speed,
+ int sample_rate_hz)
+ : filename_(filename),
+ sample_rate_hz_(sample_rate_hz),
+ speed_(speed),
+ audio_callback_(nullptr),
+ wav_reader_(nullptr),
kwiberg-webrtc 2017/03/07 10:11:57 unique_ptrs are null by default, so you don't need
+ playout_buffer_(NumSamplesPerFrame(sample_rate_hz), 0),
+ tick_(EventTimerWrapper::Create()),
+ thread_(FileReaderAudioDevice::Run, this, "FileReaderAudioDevice"),
+ done_reading_(true, true) {
+ RTC_CHECK(
+ sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
+ sample_rate_hz == 32000 || sample_rate_hz == 44100 ||
+ sample_rate_hz == 48000);
+}
+
+FileReaderAudioDevice::~FileReaderAudioDevice() {
+ StopRecording();
+}
+
+int32_t FileReaderAudioDevice::StartRecording() {
+ rtc::CritScope cs(&lock_);
+ RTC_CHECK(!wav_reader_);
+ wav_reader_.reset(new WavReader(filename_));
+ RTC_CHECK(wav_reader_->sample_rate() == sample_rate_hz_);
+ RTC_CHECK(wav_reader_->num_channels() == 1);
kwiberg-webrtc 2017/03/07 10:11:57 RTC_CHECK_EQ for these two.
oprypin_webrtc 2017/03/09 08:23:24 Done.
+
+ RTC_CHECK(tick_->StartTimer(true, kFrameLengthMs / speed_));
+ thread_.Start();
+ thread_.SetPriority(rtc::kHighPriority);
+ done_reading_.Reset();
+ return 0;
+}
+
+int32_t FileReaderAudioDevice::StopRecording() {
+ rtc::CritScope cs(&lock_);
+ wav_reader_.reset();
+ thread_.Stop();
+ return 0;
+}
+
+int32_t FileReaderAudioDevice::RegisterAudioCallback(AudioTransport* callback) {
+ rtc::CritScope cs(&lock_);
+ RTC_DCHECK(callback || audio_callback_ != nullptr);
kwiberg-webrtc 2017/03/07 10:11:57 Test code, so CHECK instead of DCHECK everywhere?
oprypin_webrtc 2017/03/09 08:23:24 Done.
+ audio_callback_ = callback;
+ return 0;
+}
+
+bool FileReaderAudioDevice::Recording() const {
+ rtc::CritScope cs(&lock_);
+ return static_cast<bool>(wav_reader_);
+}
+
+bool FileReaderAudioDevice::WaitForFileEnd(int timeout_ms) {
+ RTC_DCHECK(Recording());
+ return done_reading_.Wait(timeout_ms);
+}
+
+bool FileReaderAudioDevice::Run(void* obj) {
+ static_cast<FileReaderAudioDevice*>(obj)->ProcessAudio();
+ return true;
+}
+
+void FileReaderAudioDevice::ProcessAudio() {
+ {
+ rtc::CritScope cs(&lock_);
+ // Capture 10ms of audio. 2 bytes per sample.
+ const size_t samples_out = wav_reader_->ReadSamples(
+ playout_buffer_.size(), playout_buffer_.data());
+ if (samples_out) {
kwiberg-webrtc 2017/03/07 10:11:57 if (samples_out > 0) to emphasize that samples_ou
oprypin_webrtc 2017/03/09 08:23:24 Done.
+ RTC_CHECK(samples_out <= playout_buffer_.size());
kwiberg-webrtc 2017/03/07 10:11:57 RTC_CHECK_LE Also, move this check before line 10
oprypin_webrtc 2017/03/09 08:23:24 Done.
+ uint32_t new_mic_level;
+ audio_callback_->RecordedDataIsAvailable(
+ playout_buffer_.data(), samples_out, 2, 1,
+ sample_rate_hz_, 0, 0, 0, false, new_mic_level);
+ } else {
+ done_reading_.Set();
+ }
+ }
+ tick_->Wait(WEBRTC_EVENT_INFINITE);
+}
+
+
+FileWriterAudioDevice::FileWriterAudioDevice(std::string filename, float speed,
+ int sample_rate_hz)
+ : filename_(filename),
+ sample_rate_hz_(sample_rate_hz),
+ speed_(speed),
+ audio_callback_(nullptr),
+ wav_writer_(nullptr),
+ playout_buffer_(NumSamplesPerFrame(sample_rate_hz), 0),
+ tick_(EventTimerWrapper::Create()),
+ thread_(FileWriterAudioDevice::Run, this, "FileWriterAudioDevice") {
+ RTC_CHECK(
+ sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
+ sample_rate_hz == 32000 || sample_rate_hz == 44100 ||
+ sample_rate_hz == 48000);
+}
+
+FileWriterAudioDevice::~FileWriterAudioDevice() {
+ StopPlayout();
+}
+
+int32_t FileWriterAudioDevice::StartPlayout() {
+ rtc::CritScope cs(&lock_);
+ RTC_CHECK(!wav_writer_);
+ wav_writer_.reset(new WavWriter(filename_, sample_rate_hz_, 1));
+
+ RTC_CHECK(tick_->StartTimer(true, kFrameLengthMs / speed_));
+ thread_.Start();
+ thread_.SetPriority(rtc::kHighPriority);
+ return 0;
+}
+
+int32_t FileWriterAudioDevice::StopPlayout() {
+ rtc::CritScope cs(&lock_);
+ wav_writer_.reset(); // This also finalizes and closes the file
+ thread_.Stop();
+ return 0;
+}
+
+int32_t FileWriterAudioDevice::RegisterAudioCallback(AudioTransport* callback) {
+ rtc::CritScope cs(&lock_);
+ RTC_DCHECK(callback || audio_callback_ != nullptr);
+ audio_callback_ = callback;
+ return 0;
+}
+
+bool FileWriterAudioDevice::Playing() const {
+ rtc::CritScope cs(&lock_);
+ return static_cast<bool>(wav_writer_);
+}
+
+bool FileWriterAudioDevice::Run(void* obj) {
+ static_cast<FileWriterAudioDevice*>(obj)->ProcessAudio();
+ return true;
+}
+
+void FileWriterAudioDevice::ProcessAudio() {
+ {
+ rtc::CritScope cs(&lock_);
+ size_t samples_out;
+ int64_t elapsed_time_ms;
+ int64_t ntp_time_ms;
+ audio_callback_->NeedMorePlayData(
+ playout_buffer_.size(), 2, 1, sample_rate_hz_,
+ playout_buffer_.data(), samples_out, &elapsed_time_ms, &ntp_time_ms);
+ wav_writer_->WriteSamples(playout_buffer_.data(), samples_out);
+ }
+ tick_->Wait(WEBRTC_EVENT_INFINITE);
+}
+
+} // namespace test
+} // namespace webrtc
« webrtc/test/file_audio_device.h ('K') | « webrtc/test/file_audio_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698