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

Side by Side Diff: webrtc/modules/audio_device/android/audio_device_unittest.cc

Issue 1230503003: Update a ton of audio code to use size_t more correctly and in general reduce (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Resync Created 5 years, 3 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) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 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 <algorithm> 11 #include <algorithm>
12 #include <limits> 12 #include <limits>
13 #include <list> 13 #include <list>
14 #include <numeric> 14 #include <numeric>
15 #include <string> 15 #include <string>
16 #include <vector> 16 #include <vector>
17 17
18 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "webrtc/base/arraysize.h" 20 #include "webrtc/base/arraysize.h"
21 #include "webrtc/base/criticalsection.h" 21 #include "webrtc/base/criticalsection.h"
22 #include "webrtc/base/format_macros.h"
22 #include "webrtc/base/scoped_ptr.h" 23 #include "webrtc/base/scoped_ptr.h"
23 #include "webrtc/base/scoped_ref_ptr.h" 24 #include "webrtc/base/scoped_ref_ptr.h"
24 #include "webrtc/modules/audio_device/android/audio_common.h" 25 #include "webrtc/modules/audio_device/android/audio_common.h"
25 #include "webrtc/modules/audio_device/android/audio_manager.h" 26 #include "webrtc/modules/audio_device/android/audio_manager.h"
26 #include "webrtc/modules/audio_device/android/build_info.h" 27 #include "webrtc/modules/audio_device/android/build_info.h"
27 #include "webrtc/modules/audio_device/android/ensure_initialized.h" 28 #include "webrtc/modules/audio_device/android/ensure_initialized.h"
28 #include "webrtc/modules/audio_device/audio_device_impl.h" 29 #include "webrtc/modules/audio_device/audio_device_impl.h"
29 #include "webrtc/modules/audio_device/include/audio_device.h" 30 #include "webrtc/modules/audio_device/include/audio_device.h"
30 #include "webrtc/system_wrappers/interface/clock.h" 31 #include "webrtc/system_wrappers/interface/clock.h"
31 #include "webrtc/system_wrappers/interface/event_wrapper.h" 32 #include "webrtc/system_wrappers/interface/event_wrapper.h"
(...skipping 16 matching lines...) Expand all
48 #define PRINTD(...) fprintf(stderr, __VA_ARGS__); 49 #define PRINTD(...) fprintf(stderr, __VA_ARGS__);
49 #else 50 #else
50 #define PRINTD(...) ((void)0) 51 #define PRINTD(...) ((void)0)
51 #endif 52 #endif
52 #define PRINT(...) fprintf(stderr, __VA_ARGS__); 53 #define PRINT(...) fprintf(stderr, __VA_ARGS__);
53 54
54 namespace webrtc { 55 namespace webrtc {
55 56
56 // Number of callbacks (input or output) the tests waits for before we set 57 // Number of callbacks (input or output) the tests waits for before we set
57 // an event indicating that the test was OK. 58 // an event indicating that the test was OK.
58 static const int kNumCallbacks = 10; 59 static const size_t kNumCallbacks = 10;
59 // Max amount of time we wait for an event to be set while counting callbacks. 60 // Max amount of time we wait for an event to be set while counting callbacks.
60 static const int kTestTimeOutInMilliseconds = 10 * 1000; 61 static const int kTestTimeOutInMilliseconds = 10 * 1000;
61 // Average number of audio callbacks per second assuming 10ms packet size. 62 // Average number of audio callbacks per second assuming 10ms packet size.
62 static const int kNumCallbacksPerSecond = 100; 63 static const size_t kNumCallbacksPerSecond = 100;
63 // Play out a test file during this time (unit is in seconds). 64 // Play out a test file during this time (unit is in seconds).
64 static const int kFilePlayTimeInSec = 5; 65 static const int kFilePlayTimeInSec = 5;
65 static const int kBitsPerSample = 16; 66 static const size_t kBitsPerSample = 16;
66 static const int kBytesPerSample = kBitsPerSample / 8; 67 static const size_t kBytesPerSample = kBitsPerSample / 8;
67 // Run the full-duplex test during this time (unit is in seconds). 68 // Run the full-duplex test during this time (unit is in seconds).
68 // Note that first |kNumIgnoreFirstCallbacks| are ignored. 69 // Note that first |kNumIgnoreFirstCallbacks| are ignored.
69 static const int kFullDuplexTimeInSec = 5; 70 static const int kFullDuplexTimeInSec = 5;
70 // Wait for the callback sequence to stabilize by ignoring this amount of the 71 // Wait for the callback sequence to stabilize by ignoring this amount of the
71 // initial callbacks (avoids initial FIFO access). 72 // initial callbacks (avoids initial FIFO access).
72 // Only used in the RunPlayoutAndRecordingInFullDuplex test. 73 // Only used in the RunPlayoutAndRecordingInFullDuplex test.
73 static const int kNumIgnoreFirstCallbacks = 50; 74 static const size_t kNumIgnoreFirstCallbacks = 50;
74 // Sets the number of impulses per second in the latency test. 75 // Sets the number of impulses per second in the latency test.
75 static const int kImpulseFrequencyInHz = 1; 76 static const int kImpulseFrequencyInHz = 1;
76 // Length of round-trip latency measurements. Number of transmitted impulses 77 // Length of round-trip latency measurements. Number of transmitted impulses
77 // is kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1. 78 // is kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1.
78 static const int kMeasureLatencyTimeInSec = 11; 79 static const int kMeasureLatencyTimeInSec = 11;
79 // Utilized in round-trip latency measurements to avoid capturing noise samples. 80 // Utilized in round-trip latency measurements to avoid capturing noise samples.
80 static const int kImpulseThreshold = 1000; 81 static const int kImpulseThreshold = 1000;
81 static const char kTag[] = "[..........] "; 82 static const char kTag[] = "[..........] ";
82 83
83 enum TransportType { 84 enum TransportType {
84 kPlayout = 0x1, 85 kPlayout = 0x1,
85 kRecording = 0x2, 86 kRecording = 0x2,
86 }; 87 };
87 88
88 // Interface for processing the audio stream. Real implementations can e.g. 89 // Interface for processing the audio stream. Real implementations can e.g.
89 // run audio in loopback, read audio from a file or perform latency 90 // run audio in loopback, read audio from a file or perform latency
90 // measurements. 91 // measurements.
91 class AudioStreamInterface { 92 class AudioStreamInterface {
92 public: 93 public:
93 virtual void Write(const void* source, int num_frames) = 0; 94 virtual void Write(const void* source, size_t num_frames) = 0;
94 virtual void Read(void* destination, int num_frames) = 0; 95 virtual void Read(void* destination, size_t num_frames) = 0;
95 protected: 96 protected:
96 virtual ~AudioStreamInterface() {} 97 virtual ~AudioStreamInterface() {}
97 }; 98 };
98 99
99 // Reads audio samples from a PCM file where the file is stored in memory at 100 // Reads audio samples from a PCM file where the file is stored in memory at
100 // construction. 101 // construction.
101 class FileAudioStream : public AudioStreamInterface { 102 class FileAudioStream : public AudioStreamInterface {
102 public: 103 public:
103 FileAudioStream( 104 FileAudioStream(
104 int num_callbacks, const std::string& file_name, int sample_rate) 105 size_t num_callbacks, const std::string& file_name, int sample_rate)
105 : file_size_in_bytes_(0), 106 : file_size_in_bytes_(0),
106 sample_rate_(sample_rate), 107 sample_rate_(sample_rate),
107 file_pos_(0) { 108 file_pos_(0) {
108 file_size_in_bytes_ = test::GetFileSize(file_name); 109 file_size_in_bytes_ = test::GetFileSize(file_name);
109 sample_rate_ = sample_rate; 110 sample_rate_ = sample_rate;
110 EXPECT_GE(file_size_in_callbacks(), num_callbacks) 111 EXPECT_GE(file_size_in_callbacks(), num_callbacks)
111 << "Size of test file is not large enough to last during the test."; 112 << "Size of test file is not large enough to last during the test.";
112 const int num_16bit_samples = 113 const size_t num_16bit_samples =
113 test::GetFileSize(file_name) / kBytesPerSample; 114 test::GetFileSize(file_name) / kBytesPerSample;
114 file_.reset(new int16_t[num_16bit_samples]); 115 file_.reset(new int16_t[num_16bit_samples]);
115 FILE* audio_file = fopen(file_name.c_str(), "rb"); 116 FILE* audio_file = fopen(file_name.c_str(), "rb");
116 EXPECT_NE(audio_file, nullptr); 117 EXPECT_NE(audio_file, nullptr);
117 int num_samples_read = fread( 118 size_t num_samples_read = fread(
118 file_.get(), sizeof(int16_t), num_16bit_samples, audio_file); 119 file_.get(), sizeof(int16_t), num_16bit_samples, audio_file);
119 EXPECT_EQ(num_samples_read, num_16bit_samples); 120 EXPECT_EQ(num_samples_read, num_16bit_samples);
120 fclose(audio_file); 121 fclose(audio_file);
121 } 122 }
122 123
123 // AudioStreamInterface::Write() is not implemented. 124 // AudioStreamInterface::Write() is not implemented.
124 void Write(const void* source, int num_frames) override {} 125 void Write(const void* source, size_t num_frames) override {}
125 126
126 // Read samples from file stored in memory (at construction) and copy 127 // Read samples from file stored in memory (at construction) and copy
127 // |num_frames| (<=> 10ms) to the |destination| byte buffer. 128 // |num_frames| (<=> 10ms) to the |destination| byte buffer.
128 void Read(void* destination, int num_frames) override { 129 void Read(void* destination, size_t num_frames) override {
129 memcpy(destination, 130 memcpy(destination,
130 static_cast<int16_t*> (&file_[file_pos_]), 131 static_cast<int16_t*> (&file_[file_pos_]),
131 num_frames * sizeof(int16_t)); 132 num_frames * sizeof(int16_t));
132 file_pos_ += num_frames; 133 file_pos_ += num_frames;
133 } 134 }
134 135
135 int file_size_in_seconds() const { 136 int file_size_in_seconds() const {
136 return (file_size_in_bytes_ / (kBytesPerSample * sample_rate_)); 137 return static_cast<int>(
138 file_size_in_bytes_ / (kBytesPerSample * sample_rate_));
137 } 139 }
138 int file_size_in_callbacks() const { 140 size_t file_size_in_callbacks() const {
139 return file_size_in_seconds() * kNumCallbacksPerSecond; 141 return file_size_in_seconds() * kNumCallbacksPerSecond;
140 } 142 }
141 143
142 private: 144 private:
143 int file_size_in_bytes_; 145 size_t file_size_in_bytes_;
144 int sample_rate_; 146 int sample_rate_;
145 rtc::scoped_ptr<int16_t[]> file_; 147 rtc::scoped_ptr<int16_t[]> file_;
146 int file_pos_; 148 size_t file_pos_;
147 }; 149 };
148 150
149 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio 151 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio
150 // buffers of fixed size and allows Write and Read operations. The idea is to 152 // buffers of fixed size and allows Write and Read operations. The idea is to
151 // store recorded audio buffers (using Write) and then read (using Read) these 153 // store recorded audio buffers (using Write) and then read (using Read) these
152 // stored buffers with as short delay as possible when the audio layer needs 154 // stored buffers with as short delay as possible when the audio layer needs
153 // data to play out. The number of buffers in the FIFO will stabilize under 155 // data to play out. The number of buffers in the FIFO will stabilize under
154 // normal conditions since there will be a balance between Write and Read calls. 156 // normal conditions since there will be a balance between Write and Read calls.
155 // The container is a std::list container and access is protected with a lock 157 // The container is a std::list container and access is protected with a lock
156 // since both sides (playout and recording) are driven by its own thread. 158 // since both sides (playout and recording) are driven by its own thread.
157 class FifoAudioStream : public AudioStreamInterface { 159 class FifoAudioStream : public AudioStreamInterface {
158 public: 160 public:
159 explicit FifoAudioStream(int frames_per_buffer) 161 explicit FifoAudioStream(size_t frames_per_buffer)
160 : frames_per_buffer_(frames_per_buffer), 162 : frames_per_buffer_(frames_per_buffer),
161 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)), 163 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
162 fifo_(new AudioBufferList), 164 fifo_(new AudioBufferList),
163 largest_size_(0), 165 largest_size_(0),
164 total_written_elements_(0), 166 total_written_elements_(0),
165 write_count_(0) { 167 write_count_(0) {
166 EXPECT_NE(fifo_.get(), nullptr); 168 EXPECT_NE(fifo_.get(), nullptr);
167 } 169 }
168 170
169 ~FifoAudioStream() { 171 ~FifoAudioStream() {
170 Flush(); 172 Flush();
171 } 173 }
172 174
173 // Allocate new memory, copy |num_frames| samples from |source| into memory 175 // Allocate new memory, copy |num_frames| samples from |source| into memory
174 // and add pointer to the memory location to end of the list. 176 // and add pointer to the memory location to end of the list.
175 // Increases the size of the FIFO by one element. 177 // Increases the size of the FIFO by one element.
176 void Write(const void* source, int num_frames) override { 178 void Write(const void* source, size_t num_frames) override {
177 ASSERT_EQ(num_frames, frames_per_buffer_); 179 ASSERT_EQ(num_frames, frames_per_buffer_);
178 PRINTD("+"); 180 PRINTD("+");
179 if (write_count_++ < kNumIgnoreFirstCallbacks) { 181 if (write_count_++ < kNumIgnoreFirstCallbacks) {
180 return; 182 return;
181 } 183 }
182 int16_t* memory = new int16_t[frames_per_buffer_]; 184 int16_t* memory = new int16_t[frames_per_buffer_];
183 memcpy(static_cast<int16_t*> (&memory[0]), 185 memcpy(static_cast<int16_t*> (&memory[0]),
184 source, 186 source,
185 bytes_per_buffer_); 187 bytes_per_buffer_);
186 rtc::CritScope lock(&lock_); 188 rtc::CritScope lock(&lock_);
187 fifo_->push_back(memory); 189 fifo_->push_back(memory);
188 const int size = fifo_->size(); 190 const size_t size = fifo_->size();
189 if (size > largest_size_) { 191 if (size > largest_size_) {
190 largest_size_ = size; 192 largest_size_ = size;
191 PRINTD("(%d)", largest_size_); 193 PRINTD("(%" PRIuS ")", largest_size_);
192 } 194 }
193 total_written_elements_ += size; 195 total_written_elements_ += size;
194 } 196 }
195 197
196 // Read pointer to data buffer from front of list, copy |num_frames| of stored 198 // Read pointer to data buffer from front of list, copy |num_frames| of stored
197 // data into |destination| and delete the utilized memory allocation. 199 // data into |destination| and delete the utilized memory allocation.
198 // Decreases the size of the FIFO by one element. 200 // Decreases the size of the FIFO by one element.
199 void Read(void* destination, int num_frames) override { 201 void Read(void* destination, size_t num_frames) override {
200 ASSERT_EQ(num_frames, frames_per_buffer_); 202 ASSERT_EQ(num_frames, frames_per_buffer_);
201 PRINTD("-"); 203 PRINTD("-");
202 rtc::CritScope lock(&lock_); 204 rtc::CritScope lock(&lock_);
203 if (fifo_->empty()) { 205 if (fifo_->empty()) {
204 memset(destination, 0, bytes_per_buffer_); 206 memset(destination, 0, bytes_per_buffer_);
205 } else { 207 } else {
206 int16_t* memory = fifo_->front(); 208 int16_t* memory = fifo_->front();
207 fifo_->pop_front(); 209 fifo_->pop_front();
208 memcpy(destination, 210 memcpy(destination,
209 static_cast<int16_t*> (&memory[0]), 211 static_cast<int16_t*> (&memory[0]),
210 bytes_per_buffer_); 212 bytes_per_buffer_);
211 delete memory; 213 delete memory;
212 } 214 }
213 } 215 }
214 216
215 int size() const { 217 size_t size() const {
216 return fifo_->size(); 218 return fifo_->size();
217 } 219 }
218 220
219 int largest_size() const { 221 size_t largest_size() const {
220 return largest_size_; 222 return largest_size_;
221 } 223 }
222 224
223 int average_size() const { 225 size_t average_size() const {
224 return (total_written_elements_ == 0) ? 0.0 : 0.5 + static_cast<float> ( 226 return (total_written_elements_ == 0) ? 0.0 : 0.5 + static_cast<float> (
225 total_written_elements_) / (write_count_ - kNumIgnoreFirstCallbacks); 227 total_written_elements_) / (write_count_ - kNumIgnoreFirstCallbacks);
226 } 228 }
227 229
228 private: 230 private:
229 void Flush() { 231 void Flush() {
230 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) { 232 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) {
231 delete *it; 233 delete *it;
232 } 234 }
233 fifo_->clear(); 235 fifo_->clear();
234 } 236 }
235 237
236 using AudioBufferList = std::list<int16_t*>; 238 using AudioBufferList = std::list<int16_t*>;
237 rtc::CriticalSection lock_; 239 rtc::CriticalSection lock_;
238 const int frames_per_buffer_; 240 const size_t frames_per_buffer_;
239 const int bytes_per_buffer_; 241 const size_t bytes_per_buffer_;
240 rtc::scoped_ptr<AudioBufferList> fifo_; 242 rtc::scoped_ptr<AudioBufferList> fifo_;
241 int largest_size_; 243 size_t largest_size_;
242 int total_written_elements_; 244 size_t total_written_elements_;
243 int write_count_; 245 size_t write_count_;
244 }; 246 };
245 247
246 // Inserts periodic impulses and measures the latency between the time of 248 // Inserts periodic impulses and measures the latency between the time of
247 // transmission and time of receiving the same impulse. 249 // transmission and time of receiving the same impulse.
248 // Usage requires a special hardware called Audio Loopback Dongle. 250 // Usage requires a special hardware called Audio Loopback Dongle.
249 // See http://source.android.com/devices/audio/loopback.html for details. 251 // See http://source.android.com/devices/audio/loopback.html for details.
250 class LatencyMeasuringAudioStream : public AudioStreamInterface { 252 class LatencyMeasuringAudioStream : public AudioStreamInterface {
251 public: 253 public:
252 explicit LatencyMeasuringAudioStream(int frames_per_buffer) 254 explicit LatencyMeasuringAudioStream(size_t frames_per_buffer)
253 : clock_(Clock::GetRealTimeClock()), 255 : clock_(Clock::GetRealTimeClock()),
254 frames_per_buffer_(frames_per_buffer), 256 frames_per_buffer_(frames_per_buffer),
255 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)), 257 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
256 play_count_(0), 258 play_count_(0),
257 rec_count_(0), 259 rec_count_(0),
258 pulse_time_(0) { 260 pulse_time_(0) {
259 } 261 }
260 262
261 // Insert periodic impulses in first two samples of |destination|. 263 // Insert periodic impulses in first two samples of |destination|.
262 void Read(void* destination, int num_frames) override { 264 void Read(void* destination, size_t num_frames) override {
263 ASSERT_EQ(num_frames, frames_per_buffer_); 265 ASSERT_EQ(num_frames, frames_per_buffer_);
264 if (play_count_ == 0) { 266 if (play_count_ == 0) {
265 PRINT("["); 267 PRINT("[");
266 } 268 }
267 play_count_++; 269 play_count_++;
268 memset(destination, 0, bytes_per_buffer_); 270 memset(destination, 0, bytes_per_buffer_);
269 if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) { 271 if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) {
270 if (pulse_time_ == 0) { 272 if (pulse_time_ == 0) {
271 pulse_time_ = clock_->TimeInMilliseconds(); 273 pulse_time_ = clock_->TimeInMilliseconds();
272 } 274 }
273 PRINT("."); 275 PRINT(".");
274 const int16_t impulse = std::numeric_limits<int16_t>::max(); 276 const int16_t impulse = std::numeric_limits<int16_t>::max();
275 int16_t* ptr16 = static_cast<int16_t*> (destination); 277 int16_t* ptr16 = static_cast<int16_t*> (destination);
276 for (int i = 0; i < 2; ++i) { 278 for (size_t i = 0; i < 2; ++i) {
277 *ptr16++ = impulse; 279 ptr16[i] = impulse;
278 } 280 }
279 } 281 }
280 } 282 }
281 283
282 // Detect received impulses in |source|, derive time between transmission and 284 // Detect received impulses in |source|, derive time between transmission and
283 // detection and add the calculated delay to list of latencies. 285 // detection and add the calculated delay to list of latencies.
284 void Write(const void* source, int num_frames) override { 286 void Write(const void* source, size_t num_frames) override {
285 ASSERT_EQ(num_frames, frames_per_buffer_); 287 ASSERT_EQ(num_frames, frames_per_buffer_);
286 rec_count_++; 288 rec_count_++;
287 if (pulse_time_ == 0) { 289 if (pulse_time_ == 0) {
288 // Avoid detection of new impulse response until a new impulse has 290 // Avoid detection of new impulse response until a new impulse has
289 // been transmitted (sets |pulse_time_| to value larger than zero). 291 // been transmitted (sets |pulse_time_| to value larger than zero).
290 return; 292 return;
291 } 293 }
292 const int16_t* ptr16 = static_cast<const int16_t*> (source); 294 const int16_t* ptr16 = static_cast<const int16_t*> (source);
293 std::vector<int16_t> vec(ptr16, ptr16 + num_frames); 295 std::vector<int16_t> vec(ptr16, ptr16 + num_frames);
294 // Find max value in the audio buffer. 296 // Find max value in the audio buffer.
(...skipping 13 matching lines...) Expand all
308 // received impulse. It is transmitted at sample 0 but can be received 310 // received impulse. It is transmitted at sample 0 but can be received
309 // at sample N where N > 0. The term |extra_delay| accounts for N and it 311 // at sample N where N > 0. The term |extra_delay| accounts for N and it
310 // is a value between 0 and 10ms. 312 // is a value between 0 and 10ms.
311 latencies_.push_back(now_time - pulse_time_ + extra_delay); 313 latencies_.push_back(now_time - pulse_time_ + extra_delay);
312 pulse_time_ = 0; 314 pulse_time_ = 0;
313 } else { 315 } else {
314 PRINTD("-"); 316 PRINTD("-");
315 } 317 }
316 } 318 }
317 319
318 int num_latency_values() const { 320 size_t num_latency_values() const {
319 return latencies_.size(); 321 return latencies_.size();
320 } 322 }
321 323
322 int min_latency() const { 324 int min_latency() const {
323 if (latencies_.empty()) 325 if (latencies_.empty())
324 return 0; 326 return 0;
325 return *std::min_element(latencies_.begin(), latencies_.end()); 327 return *std::min_element(latencies_.begin(), latencies_.end());
326 } 328 }
327 329
328 int max_latency() const { 330 int max_latency() const {
(...skipping 19 matching lines...) Expand all
348 PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag, 350 PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag,
349 min_latency(), max_latency(), average_latency()); 351 min_latency(), max_latency(), average_latency());
350 } 352 }
351 353
352 int IndexToMilliseconds(double index) const { 354 int IndexToMilliseconds(double index) const {
353 return static_cast<int>(10.0 * (index / frames_per_buffer_) + 0.5); 355 return static_cast<int>(10.0 * (index / frames_per_buffer_) + 0.5);
354 } 356 }
355 357
356 private: 358 private:
357 Clock* clock_; 359 Clock* clock_;
358 const int frames_per_buffer_; 360 const size_t frames_per_buffer_;
359 const int bytes_per_buffer_; 361 const size_t bytes_per_buffer_;
360 int play_count_; 362 size_t play_count_;
361 int rec_count_; 363 size_t rec_count_;
362 int64_t pulse_time_; 364 int64_t pulse_time_;
363 std::vector<int> latencies_; 365 std::vector<int> latencies_;
364 }; 366 };
365 367
366 // Mocks the AudioTransport object and proxies actions for the two callbacks 368 // Mocks the AudioTransport object and proxies actions for the two callbacks
367 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations 369 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations
368 // of AudioStreamInterface. 370 // of AudioStreamInterface.
369 class MockAudioTransport : public AudioTransport { 371 class MockAudioTransport : public AudioTransport {
370 public: 372 public:
371 explicit MockAudioTransport(int type) 373 explicit MockAudioTransport(int type)
372 : num_callbacks_(0), 374 : num_callbacks_(0),
373 type_(type), 375 type_(type),
374 play_count_(0), 376 play_count_(0),
375 rec_count_(0), 377 rec_count_(0),
376 audio_stream_(nullptr) {} 378 audio_stream_(nullptr) {}
377 379
378 virtual ~MockAudioTransport() {} 380 virtual ~MockAudioTransport() {}
379 381
380 MOCK_METHOD10(RecordedDataIsAvailable, 382 MOCK_METHOD10(RecordedDataIsAvailable,
381 int32_t(const void* audioSamples, 383 int32_t(const void* audioSamples,
382 const uint32_t nSamples, 384 const size_t nSamples,
383 const uint8_t nBytesPerSample, 385 const size_t nBytesPerSample,
384 const uint8_t nChannels, 386 const uint8_t nChannels,
385 const uint32_t samplesPerSec, 387 const uint32_t samplesPerSec,
386 const uint32_t totalDelayMS, 388 const uint32_t totalDelayMS,
387 const int32_t clockDrift, 389 const int32_t clockDrift,
388 const uint32_t currentMicLevel, 390 const uint32_t currentMicLevel,
389 const bool keyPressed, 391 const bool keyPressed,
390 uint32_t& newMicLevel)); 392 uint32_t& newMicLevel));
391 MOCK_METHOD8(NeedMorePlayData, 393 MOCK_METHOD8(NeedMorePlayData,
392 int32_t(const uint32_t nSamples, 394 int32_t(const size_t nSamples,
393 const uint8_t nBytesPerSample, 395 const size_t nBytesPerSample,
394 const uint8_t nChannels, 396 const uint8_t nChannels,
395 const uint32_t samplesPerSec, 397 const uint32_t samplesPerSec,
396 void* audioSamples, 398 void* audioSamples,
397 uint32_t& nSamplesOut, 399 size_t& nSamplesOut,
398 int64_t* elapsed_time_ms, 400 int64_t* elapsed_time_ms,
399 int64_t* ntp_time_ms)); 401 int64_t* ntp_time_ms));
400 402
401 // Set default actions of the mock object. We are delegating to fake 403 // Set default actions of the mock object. We are delegating to fake
402 // implementations (of AudioStreamInterface) here. 404 // implementations (of AudioStreamInterface) here.
403 void HandleCallbacks(EventWrapper* test_is_done, 405 void HandleCallbacks(EventWrapper* test_is_done,
404 AudioStreamInterface* audio_stream, 406 AudioStreamInterface* audio_stream,
405 int num_callbacks) { 407 int num_callbacks) {
406 test_is_done_ = test_is_done; 408 test_is_done_ = test_is_done;
407 audio_stream_ = audio_stream; 409 audio_stream_ = audio_stream;
408 num_callbacks_ = num_callbacks; 410 num_callbacks_ = num_callbacks;
409 if (play_mode()) { 411 if (play_mode()) {
410 ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _)) 412 ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _))
411 .WillByDefault( 413 .WillByDefault(
412 Invoke(this, &MockAudioTransport::RealNeedMorePlayData)); 414 Invoke(this, &MockAudioTransport::RealNeedMorePlayData));
413 } 415 }
414 if (rec_mode()) { 416 if (rec_mode()) {
415 ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _)) 417 ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _))
416 .WillByDefault( 418 .WillByDefault(
417 Invoke(this, &MockAudioTransport::RealRecordedDataIsAvailable)); 419 Invoke(this, &MockAudioTransport::RealRecordedDataIsAvailable));
418 } 420 }
419 } 421 }
420 422
421 int32_t RealRecordedDataIsAvailable(const void* audioSamples, 423 int32_t RealRecordedDataIsAvailable(const void* audioSamples,
422 const uint32_t nSamples, 424 const size_t nSamples,
423 const uint8_t nBytesPerSample, 425 const size_t nBytesPerSample,
424 const uint8_t nChannels, 426 const uint8_t nChannels,
425 const uint32_t samplesPerSec, 427 const uint32_t samplesPerSec,
426 const uint32_t totalDelayMS, 428 const uint32_t totalDelayMS,
427 const int32_t clockDrift, 429 const int32_t clockDrift,
428 const uint32_t currentMicLevel, 430 const uint32_t currentMicLevel,
429 const bool keyPressed, 431 const bool keyPressed,
430 uint32_t& newMicLevel) { 432 uint32_t& newMicLevel) {
431 EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks."; 433 EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks.";
432 rec_count_++; 434 rec_count_++;
433 // Process the recorded audio stream if an AudioStreamInterface 435 // Process the recorded audio stream if an AudioStreamInterface
434 // implementation exists. 436 // implementation exists.
435 if (audio_stream_) { 437 if (audio_stream_) {
436 audio_stream_->Write(audioSamples, nSamples); 438 audio_stream_->Write(audioSamples, nSamples);
437 } 439 }
438 if (ReceivedEnoughCallbacks()) { 440 if (ReceivedEnoughCallbacks()) {
439 test_is_done_->Set(); 441 test_is_done_->Set();
440 } 442 }
441 return 0; 443 return 0;
442 } 444 }
443 445
444 int32_t RealNeedMorePlayData(const uint32_t nSamples, 446 int32_t RealNeedMorePlayData(const size_t nSamples,
445 const uint8_t nBytesPerSample, 447 const size_t nBytesPerSample,
446 const uint8_t nChannels, 448 const uint8_t nChannels,
447 const uint32_t samplesPerSec, 449 const uint32_t samplesPerSec,
448 void* audioSamples, 450 void* audioSamples,
449 uint32_t& nSamplesOut, 451 size_t& nSamplesOut,
450 int64_t* elapsed_time_ms, 452 int64_t* elapsed_time_ms,
451 int64_t* ntp_time_ms) { 453 int64_t* ntp_time_ms) {
452 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks."; 454 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks.";
453 play_count_++; 455 play_count_++;
454 nSamplesOut = nSamples; 456 nSamplesOut = nSamples;
455 // Read (possibly processed) audio stream samples to be played out if an 457 // Read (possibly processed) audio stream samples to be played out if an
456 // AudioStreamInterface implementation exists. 458 // AudioStreamInterface implementation exists.
457 if (audio_stream_) { 459 if (audio_stream_) {
458 audio_stream_->Read(audioSamples, nSamples); 460 audio_stream_->Read(audioSamples, nSamples);
459 } 461 }
(...skipping 17 matching lines...) Expand all
477 playout_done = true; 479 playout_done = true;
478 480
479 return recording_done && playout_done; 481 return recording_done && playout_done;
480 } 482 }
481 483
482 bool play_mode() const { return type_ & kPlayout; } 484 bool play_mode() const { return type_ & kPlayout; }
483 bool rec_mode() const { return type_ & kRecording; } 485 bool rec_mode() const { return type_ & kRecording; }
484 486
485 private: 487 private:
486 EventWrapper* test_is_done_; 488 EventWrapper* test_is_done_;
487 int num_callbacks_; 489 size_t num_callbacks_;
488 int type_; 490 int type_;
489 int play_count_; 491 size_t play_count_;
490 int rec_count_; 492 size_t rec_count_;
491 AudioStreamInterface* audio_stream_; 493 AudioStreamInterface* audio_stream_;
492 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream_; 494 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream_;
493 }; 495 };
494 496
495 // AudioDeviceTest test fixture. 497 // AudioDeviceTest test fixture.
496 class AudioDeviceTest : public ::testing::Test { 498 class AudioDeviceTest : public ::testing::Test {
497 protected: 499 protected:
498 AudioDeviceTest() 500 AudioDeviceTest()
499 : test_is_done_(EventWrapper::Create()) { 501 : test_is_done_(EventWrapper::Create()) {
500 // One-time initialization of JVM and application context. Ensures that we 502 // One-time initialization of JVM and application context. Ensures that we
(...skipping 17 matching lines...) Expand all
518 } 520 }
519 int record_sample_rate() const { 521 int record_sample_rate() const {
520 return record_parameters_.sample_rate(); 522 return record_parameters_.sample_rate();
521 } 523 }
522 int playout_channels() const { 524 int playout_channels() const {
523 return playout_parameters_.channels(); 525 return playout_parameters_.channels();
524 } 526 }
525 int record_channels() const { 527 int record_channels() const {
526 return record_parameters_.channels(); 528 return record_parameters_.channels();
527 } 529 }
528 int playout_frames_per_10ms_buffer() const { 530 size_t playout_frames_per_10ms_buffer() const {
529 return playout_parameters_.frames_per_10ms_buffer(); 531 return playout_parameters_.frames_per_10ms_buffer();
530 } 532 }
531 int record_frames_per_10ms_buffer() const { 533 size_t record_frames_per_10ms_buffer() const {
532 return record_parameters_.frames_per_10ms_buffer(); 534 return record_parameters_.frames_per_10ms_buffer();
533 } 535 }
534 536
535 int total_delay_ms() const { 537 int total_delay_ms() const {
536 return audio_manager()->GetDelayEstimateInMilliseconds(); 538 return audio_manager()->GetDelayEstimateInMilliseconds();
537 } 539 }
538 540
539 rtc::scoped_refptr<AudioDeviceModule> audio_device() const { 541 rtc::scoped_refptr<AudioDeviceModule> audio_device() const {
540 return audio_device_; 542 return audio_device_;
541 } 543 }
(...skipping 27 matching lines...) Expand all
569 EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100); 571 EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100);
570 char fname[64]; 572 char fname[64];
571 snprintf(fname, 573 snprintf(fname,
572 sizeof(fname), 574 sizeof(fname),
573 "audio_device/audio_short%d", 575 "audio_device/audio_short%d",
574 sample_rate / 1000); 576 sample_rate / 1000);
575 std::string file_name(webrtc::test::ResourcePath(fname, "pcm")); 577 std::string file_name(webrtc::test::ResourcePath(fname, "pcm"));
576 EXPECT_TRUE(test::FileExists(file_name)); 578 EXPECT_TRUE(test::FileExists(file_name));
577 #ifdef ENABLE_PRINTF 579 #ifdef ENABLE_PRINTF
578 PRINT("file name: %s\n", file_name.c_str()); 580 PRINT("file name: %s\n", file_name.c_str());
579 const int bytes = test::GetFileSize(file_name); 581 const size_t bytes = test::GetFileSize(file_name);
580 PRINT("file size: %d [bytes]\n", bytes); 582 PRINT("file size: %" PRIuS " [bytes]\n", bytes);
581 PRINT("file size: %d [samples]\n", bytes / kBytesPerSample); 583 PRINT("file size: %" PRIuS " [samples]\n", bytes / kBytesPerSample);
582 const int seconds = bytes / (sample_rate * kBytesPerSample); 584 const int seconds =
585 static_cast<int>(bytes / (sample_rate * kBytesPerSample));
583 PRINT("file size: %d [secs]\n", seconds); 586 PRINT("file size: %d [secs]\n", seconds);
584 PRINT("file size: %d [callbacks]\n", seconds * kNumCallbacksPerSecond); 587 PRINT("file size: %" PRIuS " [callbacks]\n",
588 seconds * kNumCallbacksPerSecond);
585 #endif 589 #endif
586 return file_name; 590 return file_name;
587 } 591 }
588 592
589 AudioDeviceModule::AudioLayer GetActiveAudioLayer() const { 593 AudioDeviceModule::AudioLayer GetActiveAudioLayer() const {
590 AudioDeviceModule::AudioLayer audio_layer; 594 AudioDeviceModule::AudioLayer audio_layer;
591 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer)); 595 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer));
592 return audio_layer; 596 return audio_layer;
593 } 597 }
594 598
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 fifo_audio_stream.get(), 958 fifo_audio_stream.get(),
955 kFullDuplexTimeInSec * kNumCallbacksPerSecond); 959 kFullDuplexTimeInSec * kNumCallbacksPerSecond);
956 SetMaxPlayoutVolume(); 960 SetMaxPlayoutVolume();
957 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 961 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
958 StartRecording(); 962 StartRecording();
959 StartPlayout(); 963 StartPlayout();
960 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, 964 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds,
961 1000 * kFullDuplexTimeInSec)); 965 1000 * kFullDuplexTimeInSec));
962 StopPlayout(); 966 StopPlayout();
963 StopRecording(); 967 StopRecording();
964 EXPECT_LE(fifo_audio_stream->average_size(), 10); 968 EXPECT_LE(fifo_audio_stream->average_size(), 10u);
965 EXPECT_LE(fifo_audio_stream->largest_size(), 20); 969 EXPECT_LE(fifo_audio_stream->largest_size(), 20u);
966 } 970 }
967 971
968 // Measures loopback latency and reports the min, max and average values for 972 // Measures loopback latency and reports the min, max and average values for
969 // a full duplex audio session. 973 // a full duplex audio session.
970 // The latency is measured like so: 974 // The latency is measured like so:
971 // - Insert impulses periodically on the output side. 975 // - Insert impulses periodically on the output side.
972 // - Detect the impulses on the input side. 976 // - Detect the impulses on the input side.
973 // - Measure the time difference between the transmit time and receive time. 977 // - Measure the time difference between the transmit time and receive time.
974 // - Store time differences in a vector and calculate min, max and average. 978 // - Store time differences in a vector and calculate min, max and average.
975 // This test requires a special hardware called Audio Loopback Dongle. 979 // This test requires a special hardware called Audio Loopback Dongle.
(...skipping 11 matching lines...) Expand all
987 SetMaxPlayoutVolume(); 991 SetMaxPlayoutVolume();
988 DisableBuiltInAECIfAvailable(); 992 DisableBuiltInAECIfAvailable();
989 StartRecording(); 993 StartRecording();
990 StartPlayout(); 994 StartPlayout();
991 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, 995 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds,
992 1000 * kMeasureLatencyTimeInSec)); 996 1000 * kMeasureLatencyTimeInSec));
993 StopPlayout(); 997 StopPlayout();
994 StopRecording(); 998 StopRecording();
995 // Verify that the correct number of transmitted impulses are detected. 999 // Verify that the correct number of transmitted impulses are detected.
996 EXPECT_EQ(latency_audio_stream->num_latency_values(), 1000 EXPECT_EQ(latency_audio_stream->num_latency_values(),
997 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1); 1001 static_cast<size_t>(
1002 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1));
998 latency_audio_stream->PrintResults(); 1003 latency_audio_stream->PrintResults();
999 } 1004 }
1000 1005
1001 } // namespace webrtc 1006 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_device/android/audio_common.h ('k') | webrtc/modules/audio_device/android/audio_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698