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 |