Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license | |
| 5 * that can be found in the LICENSE file in the root of the source | |
| 6 * tree. An additional intellectual property rights grant can be found | |
| 7 * in the file PATENTS. All contributing project authors may | |
| 8 * be found in the AUTHORS file in the root of the source tree. | |
| 9 */ | |
| 10 | |
| 11 #include "webrtc/test/file_audio_device.h" | |
| 12 | |
| 13 #include <algorithm> | |
| 14 | |
| 15 #include "webrtc/base/checks.h" | |
| 16 #include "webrtc/system_wrappers/include/event_wrapper.h" | |
| 17 | |
| 18 namespace webrtc { | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 constexpr int kFrameLengthMs = 10; | |
| 23 constexpr int kFramesPerSecond = 1000 / kFrameLengthMs; | |
| 24 | |
| 25 } // namespace | |
| 26 namespace test { | |
| 27 | |
| 28 FileAudioDevice::FileAudioDevice(const std::string& filename, | |
| 29 float speed, int sampling_frequency_in_hz) | |
| 30 : 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.
| |
| 31 sampling_frequency_in_hz_(sampling_frequency_in_hz), | |
| 32 num_samples_per_frame_( | |
| 33 rtc::CheckedDivExact(sampling_frequency_in_hz_, kFramesPerSecond)), | |
| 34 speed_(speed), | |
| 35 audio_callback_(nullptr), | |
| 36 wav_reader_(nullptr), | |
| 37 wav_writer_(nullptr), | |
| 38 playout_buffer_(num_samples_per_frame_, 0), | |
| 39 tick_(EventTimerWrapper::Create()), | |
| 40 thread_(FileAudioDevice::Run, this, "FileAudioDevice"), | |
| 41 done_reading_(true, true) { | |
| 42 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
| |
| 43 sampling_frequency_in_hz == 8000 || sampling_frequency_in_hz == 16000 || | |
| 44 sampling_frequency_in_hz == 32000 || sampling_frequency_in_hz == 44100 || | |
| 45 sampling_frequency_in_hz == 48000); | |
| 46 } | |
| 47 | |
| 48 FileAudioDevice::~FileAudioDevice() { | |
| 49 StopPlayout(); | |
| 50 StopRecording(); | |
| 51 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
| |
| 52 } | |
| 53 | |
| 54 int32_t FileAudioDevice::StartPlayout() { | |
| 55 rtc::CritScope cs(&lock_); | |
| 56 RTC_CHECK(!wav_reader_); | |
| 57 RTC_CHECK(!wav_writer_); | |
| 58 wav_writer_.reset(new WavWriter(filename_, sampling_frequency_in_hz_, 1)); | |
| 59 return 0; | |
| 60 } | |
| 61 | |
| 62 int32_t FileAudioDevice::StopPlayout() { | |
| 63 rtc::CritScope cs(&lock_); | |
| 64 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
| |
| 65 return 0; | |
| 66 } | |
| 67 | |
| 68 int32_t FileAudioDevice::StartRecording() { | |
| 69 rtc::CritScope cs(&lock_); | |
| 70 RTC_CHECK(!wav_reader_); | |
| 71 RTC_CHECK(!wav_writer_); | |
| 72 done_reading_.Reset(); | |
| 73 wav_reader_.reset(new WavReader(filename_)); | |
| 74 return 0; | |
| 75 } | |
| 76 | |
| 77 int32_t FileAudioDevice::StopRecording() { | |
| 78 rtc::CritScope cs(&lock_); | |
| 79 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
| |
| 80 return 0; | |
| 81 } | |
| 82 | |
| 83 int32_t FileAudioDevice::Init() { | |
| 84 RTC_CHECK(tick_->StartTimer(true, kFrameLengthMs / speed_)); | |
| 85 thread_.Start(); | |
| 86 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
| |
| 87 return 0; | |
| 88 } | |
| 89 | |
| 90 int32_t FileAudioDevice::RegisterAudioCallback(AudioTransport* callback) { | |
| 91 rtc::CritScope cs(&lock_); | |
| 92 RTC_DCHECK(callback || audio_callback_ != nullptr); | |
| 93 audio_callback_ = callback; | |
| 94 return 0; | |
| 95 } | |
| 96 | |
| 97 bool FileAudioDevice::Playing() const { | |
| 98 rtc::CritScope cs(&lock_); | |
| 99 return static_cast<bool>(wav_writer_); | |
| 100 } | |
| 101 | |
| 102 bool FileAudioDevice::Recording() const { | |
| 103 rtc::CritScope cs(&lock_); | |
| 104 return static_cast<bool>(wav_reader_); | |
| 105 } | |
| 106 | |
| 107 bool FileAudioDevice::WaitForFileEnd(int milliseconds) { | |
| 108 RTC_DCHECK(Recording()); | |
| 109 return done_reading_.Wait(milliseconds); | |
| 110 } | |
| 111 | |
| 112 bool FileAudioDevice::Run(void* obj) { | |
| 113 static_cast<FileAudioDevice*>(obj)->ProcessAudio(); | |
| 114 return true; | |
| 115 } | |
|
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
| |
| 116 | |
| 117 void FileAudioDevice::ProcessAudio() { | |
| 118 { | |
| 119 rtc::CritScope cs(&lock_); | |
| 120 if (wav_reader_) { | |
| 121 // Capture 10ms of audio. 2 bytes per sample. | |
| 122 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.
| |
| 123 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.
| |
| 124 if (samples_out) { | |
| 125 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.
| |
| 126 audio_callback_->RecordedDataIsAvailable( | |
| 127 playout_buffer_.data(), samples_out, 2, 1, | |
| 128 sampling_frequency_in_hz_, 0, 0, 0, false, new_mic_level); | |
| 129 } else { | |
| 130 done_reading_.Set(); | |
| 131 } | |
| 132 } | |
| 133 if (wav_writer_) { | |
| 134 size_t samples_out = 0; | |
| 135 int64_t elapsed_time_ms = -1; | |
| 136 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
| |
| 137 audio_callback_->NeedMorePlayData( | |
| 138 num_samples_per_frame_, 2, 1, sampling_frequency_in_hz_, | |
| 139 playout_buffer_.data(), samples_out, &elapsed_time_ms, &ntp_time_ms); | |
| 140 wav_writer_->WriteSamples(playout_buffer_.data(), samples_out); | |
| 141 } | |
|
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
| |
| 142 } | |
| 143 tick_->Wait(WEBRTC_EVENT_INFINITE); | |
| 144 } | |
| 145 | |
| 146 } // namespace test | |
| 147 } // namespace webrtc | |
| OLD | NEW |