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..eb8a8ff9c9693bc054db3595d2b19bbfc36c7ecb |
--- /dev/null |
+++ b/webrtc/test/file_audio_device.cc |
@@ -0,0 +1,147 @@ |
+/* |
+ * 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; |
+ |
+} // namespace |
+namespace test { |
+ |
+FileAudioDevice::FileAudioDevice(const std::string& filename, |
+ float speed, int sampling_frequency_in_hz) |
+ : filename_(filename), |
kwiberg-webrtc
2017/02/28 13:43:47
Since you always copy the filename, take it by val
oprypin_webrtc
2017/03/06 16:45:00
Done.
|
+ sampling_frequency_in_hz_(sampling_frequency_in_hz), |
+ num_samples_per_frame_( |
+ rtc::CheckedDivExact(sampling_frequency_in_hz_, kFramesPerSecond)), |
+ speed_(speed), |
+ audio_callback_(nullptr), |
+ wav_reader_(nullptr), |
+ wav_writer_(nullptr), |
+ playout_buffer_(num_samples_per_frame_, 0), |
+ tick_(EventTimerWrapper::Create()), |
+ thread_(FileAudioDevice::Run, this, "FileAudioDevice"), |
+ done_reading_(true, true) { |
+ RTC_DCHECK( |
kwiberg-webrtc
2017/02/28 13:43:46
Since this is test code, there's no reason not to
oprypin_webrtc
2017/03/06 16:45:00
Just did the same as in FakeAudioDevice.
Changed t
|
+ sampling_frequency_in_hz == 8000 || sampling_frequency_in_hz == 16000 || |
+ sampling_frequency_in_hz == 32000 || sampling_frequency_in_hz == 44100 || |
+ sampling_frequency_in_hz == 48000); |
+} |
+ |
+FileAudioDevice::~FileAudioDevice() { |
+ StopPlayout(); |
+ StopRecording(); |
+ thread_.Stop(); |
kwiberg-webrtc
2017/02/28 13:43:46
Why not stop the thread first? (Just asking---I do
oprypin_webrtc
2017/03/06 16:45:00
Just did the same as in FakeAudioDevice.
The order
|
+} |
+ |
+int32_t FileAudioDevice::StartPlayout() { |
+ rtc::CritScope cs(&lock_); |
+ RTC_CHECK(!wav_reader_); |
+ RTC_CHECK(!wav_writer_); |
+ wav_writer_.reset(new WavWriter(filename_, sampling_frequency_in_hz_, 1)); |
+ return 0; |
+} |
+ |
+int32_t FileAudioDevice::StopPlayout() { |
+ rtc::CritScope cs(&lock_); |
+ wav_writer_.reset(nullptr); |
kwiberg-webrtc
2017/02/28 13:43:47
It's better to do either
wav_writer_.reset();
oprypin_webrtc
2017/03/06 16:45:00
For some reason I thought `reset()` is a newer fea
|
+ return 0; |
+} |
+ |
+int32_t FileAudioDevice::StartRecording() { |
+ rtc::CritScope cs(&lock_); |
+ RTC_CHECK(!wav_reader_); |
+ RTC_CHECK(!wav_writer_); |
+ done_reading_.Reset(); |
+ wav_reader_.reset(new WavReader(filename_)); |
+ return 0; |
+} |
+ |
+int32_t FileAudioDevice::StopRecording() { |
+ rtc::CritScope cs(&lock_); |
+ wav_reader_.reset(nullptr); // This also finalizes and closes the file |
kwiberg-webrtc
2017/02/28 13:43:46
Maybe nothing to fix, but you don't have this comm
oprypin_webrtc
2017/03/06 16:45:00
Hm, this is supposed to be a comment for WavWriter
|
+ return 0; |
+} |
+ |
+int32_t FileAudioDevice::Init() { |
+ RTC_CHECK(tick_->StartTimer(true, kFrameLengthMs / speed_)); |
+ thread_.Start(); |
+ thread_.SetPriority(rtc::kHighPriority); |
kwiberg-webrtc
2017/02/28 13:43:46
Do these two in the other order? (Again, just the
oprypin_webrtc
2017/03/06 16:45:00
A code search shows that it's always done in this
|
+ return 0; |
+} |
+ |
+int32_t FileAudioDevice::RegisterAudioCallback(AudioTransport* callback) { |
+ rtc::CritScope cs(&lock_); |
+ RTC_DCHECK(callback || audio_callback_ != nullptr); |
+ audio_callback_ = callback; |
+ return 0; |
+} |
+ |
+bool FileAudioDevice::Playing() const { |
+ rtc::CritScope cs(&lock_); |
+ return static_cast<bool>(wav_writer_); |
+} |
+ |
+bool FileAudioDevice::Recording() const { |
+ rtc::CritScope cs(&lock_); |
+ return static_cast<bool>(wav_reader_); |
+} |
+ |
+bool FileAudioDevice::WaitForFileEnd(int milliseconds) { |
+ RTC_DCHECK(Recording()); |
+ return done_reading_.Wait(milliseconds); |
+} |
+ |
+bool FileAudioDevice::Run(void* obj) { |
+ static_cast<FileAudioDevice*>(obj)->ProcessAudio(); |
+ return true; |
+} |
kwiberg-webrtc
2017/02/28 13:43:46
This doesn't need to be a member function. It can
oprypin_webrtc
2017/03/06 16:45:00
I've tried turning it into a lambda, but getting t
kwiberg-webrtc
2017/03/07 10:11:57
On what line? That makes no sense at all to me. A
|
+ |
+void FileAudioDevice::ProcessAudio() { |
+ { |
+ rtc::CritScope cs(&lock_); |
+ if (wav_reader_) { |
+ // Capture 10ms of audio. 2 bytes per sample. |
+ size_t samples_out = wav_reader_->ReadSamples(num_samples_per_frame_, |
kwiberg-webrtc
2017/02/28 13:43:47
const
oprypin_webrtc
2017/03/06 16:45:00
Done.
|
+ playout_buffer_.data()); |
kwiberg-webrtc
2017/02/28 13:43:47
CHECK that samples_out <= playout_buffer_.size()?
oprypin_webrtc
2017/03/06 16:45:00
Done.
|
+ if (samples_out) { |
+ uint32_t new_mic_level = 0; |
kwiberg-webrtc
2017/02/28 13:43:46
Don't initialize if you don't have to.
oprypin_webrtc
2017/03/06 16:45:00
Done.
|
+ audio_callback_->RecordedDataIsAvailable( |
+ playout_buffer_.data(), samples_out, 2, 1, |
+ sampling_frequency_in_hz_, 0, 0, 0, false, new_mic_level); |
+ } else { |
+ done_reading_.Set(); |
+ } |
+ } |
+ if (wav_writer_) { |
+ size_t samples_out = 0; |
+ int64_t elapsed_time_ms = -1; |
+ int64_t ntp_time_ms = -1; |
kwiberg-webrtc
2017/02/28 13:43:46
Don't initialize here either. In particular, since
oprypin_webrtc
2017/03/06 16:45:00
Thanks, good to know. Again I just took FakeAudioD
|
+ audio_callback_->NeedMorePlayData( |
+ num_samples_per_frame_, 2, 1, sampling_frequency_in_hz_, |
+ playout_buffer_.data(), samples_out, &elapsed_time_ms, &ntp_time_ms); |
+ wav_writer_->WriteSamples(playout_buffer_.data(), samples_out); |
+ } |
kwiberg-webrtc
2017/02/28 13:43:47
Since playout_buffer_ is only used locally in this
oprypin_webrtc
2017/03/06 16:45:00
I don't see how I can use an array of a constant s
kwiberg-webrtc
2017/03/07 10:11:57
Just the sample rate, which is capped at 48 kHz. I
|
+ } |
+ tick_->Wait(WEBRTC_EVENT_INFINITE); |
+} |
+ |
+} // namespace test |
+} // namespace webrtc |