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

Side by Side Diff: webrtc/test/fake_audio_device.cc

Issue 2652803002: Refactor FakeAudioDevice to have separate methods for starting recording and playout. (Closed)
Patch Set: Use 48000KHz sample rate. Changed from sine to a noise pulse. Created 3 years, 10 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/test/fake_audio_device.h" 11 #include "webrtc/test/fake_audio_device.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 14
15 #include "webrtc/base/platform_thread.h" 15 #include "webrtc/base/random.h"
16 #include "webrtc/modules/media_file/media_file_utility.h"
17 #include "webrtc/system_wrappers/include/clock.h" 16 #include "webrtc/system_wrappers/include/clock.h"
18 #include "webrtc/system_wrappers/include/event_wrapper.h" 17 #include "webrtc/system_wrappers/include/event_wrapper.h"
19 #include "webrtc/system_wrappers/include/file_wrapper.h"
20 #include "webrtc/test/gtest.h"
21 18
22 namespace webrtc { 19 namespace webrtc {
23 namespace test { 20 namespace test {
24 21
22 class FakeAudioDevice::PulsedNoiseCapturer {
23 public:
24 PulsedNoiseCapturer(size_t num_samples, int16_t max_amplitude)
25 : fill_with_zero_(false) {
26 RTC_DCHECK_GT(max_amplitude, 0);
27 random_audio_.SetSize(num_samples);
peah-webrtc 2017/01/26 09:23:59 Instead add random_audio_(num_samples, 0) to the i
perkj_webrtc 2017/01/26 12:16:25 Done.
28 null_audio_.SetSize(num_samples);
peah-webrtc 2017/01/26 09:23:59 Instead add null_audio_(num_samples, 0) to the ini
perkj_webrtc 2017/01/26 12:16:25 Done.
29 memset(null_audio_.data(), 0, null_audio_.size() * sizeof(int16_t));
peah-webrtc 2017/01/26 09:23:59 This can be removed if you use a vector instead.
perkj_webrtc 2017/01/26 12:16:25 I did not know I could use a std::vector. c++11 ne
30
31 webrtc::Random random_generator(1);
32 for (size_t i = 0; i < num_samples; ++i) {
peah-webrtc 2017/01/26 09:23:59 You can instead use for (auto& r : random_audio_)
perkj_webrtc 2017/01/26 12:16:25 ok, I did that first but decided against it since
33 random_audio_[i] = random_generator.Rand(-max_amplitude, max_amplitude);
34 }
35 }
36
37 rtc::ArrayView<int16_t> Capture() {
peah-webrtc 2017/01/26 09:23:59 rtc::ArrayView<int16_t> returns an object that can
perkj_webrtc 2017/01/26 12:16:25 Done.
38 fill_with_zero_ = !fill_with_zero_;
peah-webrtc 2017/01/26 09:23:59 I think you should do this with proper (nonrepeati
perkj_webrtc 2017/01/26 12:16:25 nice. I like std::generate.
39 return fill_with_zero_ ? null_audio_ : random_audio_;
40 }
41
42 private:
43 bool fill_with_zero_;
44 rtc::BufferT<int16_t> random_audio_;
peah-webrtc 2017/01/26 09:23:59 Since the sizes of these are constant, I'd rather
perkj_webrtc 2017/01/26 12:16:25 sure, I did not know about std::vector::data()
45 rtc::BufferT<int16_t> null_audio_;
46 };
47
25 FakeAudioDevice::FakeAudioDevice(Clock* clock, 48 FakeAudioDevice::FakeAudioDevice(Clock* clock,
26 const std::string& filename, 49 float speed,
27 float speed) 50 int sampling_frequency_in_hz)
28 : audio_callback_(NULL), 51 : sampling_frequency_in_hz_(sampling_frequency_in_hz),
29 capturing_(false), 52 audio_callback_(NULL),
30 captured_audio_(), 53 rendering_(false),
31 playout_buffer_(),
32 speed_(speed), 54 speed_(speed),
33 last_playout_ms_(-1), 55 last_playout_ms_(-1),
34 clock_(clock, speed), 56 clock_(clock, speed),
35 tick_(EventTimerWrapper::Create()), 57 tick_(EventTimerWrapper::Create()),
36 thread_(FakeAudioDevice::Run, this, "FakeAudioDevice"), 58 thread_(FakeAudioDevice::Run, this, "FakeAudioDevice") {
37 file_utility_(new ModuleFileUtility(0)), 59 // Assuming 10ms audio packets.
38 input_stream_(FileWrapper::Create()) { 60 playout_buffer_.SetSize(sampling_frequency_in_hz_ / 100);
peah-webrtc 2017/01/26 09:23:59 Change this to vector, and set the size in the ini
perkj_webrtc 2017/01/26 12:16:25 Done.
39 memset(captured_audio_, 0, sizeof(captured_audio_));
40 memset(playout_buffer_, 0, sizeof(playout_buffer_));
41 // Open audio input file as read-only and looping.
42 EXPECT_TRUE(input_stream_->OpenFile(filename.c_str(), true)) << filename;
43 } 61 }
44 62
45 FakeAudioDevice::~FakeAudioDevice() { 63 FakeAudioDevice::~FakeAudioDevice() {
46 Stop(); 64 StopPlayout();
47 65 StopRecording();
48 thread_.Stop(); 66 thread_.Stop();
49 } 67 }
50 68
69 int32_t FakeAudioDevice::StartPlayout() {
70 rtc::CritScope cs(&lock_);
71 rendering_ = true;
72 return 0;
73 }
74
75 int32_t FakeAudioDevice::StopPlayout() {
76 rtc::CritScope cs(&lock_);
77 rendering_ = false;
78 return 0;
79 }
80
81 void FakeAudioDevice::StartRecordingPulsedNoise(int16_t max_amplitude) {
82 rtc::CritScope cs(&lock_);
83 capturer_.reset(new FakeAudioDevice::PulsedNoiseCapturer(
84 sampling_frequency_in_hz_ / 100, max_amplitude));
85 }
86
87 int32_t FakeAudioDevice::StopRecording() {
88 rtc::CritScope cs(&lock_);
89 capturer_.reset();
90 return 0;
91 }
92
51 int32_t FakeAudioDevice::Init() { 93 int32_t FakeAudioDevice::Init() {
52 rtc::CritScope cs(&lock_); 94 RTC_CHECK(tick_->StartTimer(true, 10 / speed_));
53 if (file_utility_->InitPCMReading(*input_stream_.get()) != 0)
54 return -1;
55
56 if (!tick_->StartTimer(true, 10 / speed_))
57 return -1;
58 thread_.Start(); 95 thread_.Start();
59 thread_.SetPriority(rtc::kHighPriority); 96 thread_.SetPriority(rtc::kHighPriority);
60 return 0; 97 return 0;
61 } 98 }
62 99
63 int32_t FakeAudioDevice::RegisterAudioCallback(AudioTransport* callback) { 100 int32_t FakeAudioDevice::RegisterAudioCallback(AudioTransport* callback) {
64 rtc::CritScope cs(&lock_); 101 rtc::CritScope cs(&lock_);
65 audio_callback_ = callback; 102 audio_callback_ = callback;
66 return 0; 103 return 0;
67 } 104 }
68 105
69 bool FakeAudioDevice::Playing() const { 106 bool FakeAudioDevice::Playing() const {
70 rtc::CritScope cs(&lock_); 107 rtc::CritScope cs(&lock_);
71 return capturing_; 108 return rendering_;
72 } 109 }
73 110
74 int32_t FakeAudioDevice::PlayoutDelay(uint16_t* delay_ms) const { 111 int32_t FakeAudioDevice::PlayoutDelay(uint16_t* delay_ms) const {
75 *delay_ms = 0; 112 *delay_ms = 0;
76 return 0; 113 return 0;
77 } 114 }
78 115
79 bool FakeAudioDevice::Recording() const { 116 bool FakeAudioDevice::Recording() const {
80 rtc::CritScope cs(&lock_); 117 rtc::CritScope cs(&lock_);
81 return capturing_; 118 return !!capturer_;
82 } 119 }
83 120
84 bool FakeAudioDevice::Run(void* obj) { 121 bool FakeAudioDevice::Run(void* obj) {
85 static_cast<FakeAudioDevice*>(obj)->CaptureAudio(); 122 static_cast<FakeAudioDevice*>(obj)->ProcessAudio();
86 return true; 123 return true;
87 } 124 }
88 125
89 void FakeAudioDevice::CaptureAudio() { 126 void FakeAudioDevice::ProcessAudio() {
90 { 127 {
91 rtc::CritScope cs(&lock_); 128 rtc::CritScope cs(&lock_);
92 if (capturing_) { 129 if (capturer_) {
93 int bytes_read = file_utility_->ReadPCMData( 130 // Capture 10ms of audio. 2 bytes per sample.
94 *input_stream_.get(), captured_audio_, kBufferSizeBytes); 131 rtc::ArrayView<int16_t> audio_data = capturer_->Capture();
95 if (bytes_read <= 0)
96 return;
97 // 2 bytes per sample.
98 size_t num_samples = static_cast<size_t>(bytes_read / 2);
99 uint32_t new_mic_level; 132 uint32_t new_mic_level;
100 EXPECT_EQ(0, 133 RTC_CHECK_EQ(
101 audio_callback_->RecordedDataIsAvailable(captured_audio_, 134 0, audio_callback_->RecordedDataIsAvailable(
102 num_samples, 135 audio_data.data(), audio_data.size(), 2, 1,
103 2, 136 sampling_frequency_in_hz_, 0, 0, 0, false, new_mic_level));
104 1, 137 }
105 kFrequencyHz, 138 if (rendering_) {
106 0, 139 // Assuming 10ms audio packet size.
107 0, 140 size_t samples_needed = sampling_frequency_in_hz_ / 100;
108 0,
109 false,
110 new_mic_level));
111 size_t samples_needed = kFrequencyHz / 100;
112 int64_t now_ms = clock_.TimeInMilliseconds(); 141 int64_t now_ms = clock_.TimeInMilliseconds();
113 uint32_t time_since_last_playout_ms = now_ms - last_playout_ms_; 142 uint32_t time_since_last_playout_ms = now_ms - last_playout_ms_;
114 if (last_playout_ms_ > 0 && time_since_last_playout_ms > 0) { 143 if (last_playout_ms_ > 0 && time_since_last_playout_ms > 0) {
115 samples_needed = std::min( 144 samples_needed =
116 static_cast<size_t>(kFrequencyHz / time_since_last_playout_ms), 145 std::min(static_cast<size_t>(sampling_frequency_in_hz_ /
117 kBufferSizeBytes / 2); 146 time_since_last_playout_ms),
147 playout_buffer_.size());
118 } 148 }
119 size_t samples_out = 0; 149 size_t samples_out = 0;
120 int64_t elapsed_time_ms = -1; 150 int64_t elapsed_time_ms = -1;
121 int64_t ntp_time_ms = -1; 151 int64_t ntp_time_ms = -1;
122 EXPECT_EQ(0, 152 RTC_CHECK_EQ(0, audio_callback_->NeedMorePlayData(
123 audio_callback_->NeedMorePlayData(samples_needed, 153 samples_needed, 2, 1, sampling_frequency_in_hz_,
124 2, 154 playout_buffer_.data(), samples_out, &elapsed_time_ms,
125 1, 155 &ntp_time_ms));
126 kFrequencyHz,
127 playout_buffer_,
128 samples_out,
129 &elapsed_time_ms,
130 &ntp_time_ms));
131 } 156 }
132 } 157 }
133 tick_->Wait(WEBRTC_EVENT_INFINITE); 158 tick_->Wait(WEBRTC_EVENT_INFINITE);
134 } 159 }
135 160
136 void FakeAudioDevice::Start() {
137 rtc::CritScope cs(&lock_);
138 capturing_ = true;
139 }
140 161
141 void FakeAudioDevice::Stop() {
142 rtc::CritScope cs(&lock_);
143 capturing_ = false;
144 }
145 } // namespace test 162 } // namespace test
146 } // namespace webrtc 163 } // namespace webrtc
OLDNEW
« webrtc/test/fake_audio_device.h ('K') | « webrtc/test/fake_audio_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698