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

Side by Side Diff: webrtc/modules/audio_device/ios/audio_device_unittest_ios.cc

Issue 1206783002: Cleanup of iOS AudioDevice implementation (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased Created 5 years, 5 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/logging.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_manager.h"
26 #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/audio_device_impl.h" 25 #include "webrtc/modules/audio_device/audio_device_impl.h"
29 #include "webrtc/modules/audio_device/include/audio_device.h" 26 #include "webrtc/modules/audio_device/include/audio_device.h"
27 #include "webrtc/modules/audio_device/ios/audio_device_ios.h"
30 #include "webrtc/system_wrappers/interface/clock.h" 28 #include "webrtc/system_wrappers/interface/clock.h"
31 #include "webrtc/system_wrappers/interface/event_wrapper.h" 29 #include "webrtc/system_wrappers/interface/event_wrapper.h"
32 #include "webrtc/system_wrappers/interface/sleep.h" 30 #include "webrtc/system_wrappers/interface/sleep.h"
33 #include "webrtc/test/testsupport/fileutils.h" 31 #include "webrtc/test/testsupport/fileutils.h"
34 32
35 using std::cout; 33 using std::cout;
36 using std::endl; 34 using std::endl;
37 using ::testing::_; 35 using ::testing::_;
38 using ::testing::AtLeast; 36 using ::testing::AtLeast;
39 using ::testing::Gt; 37 using ::testing::Gt;
40 using ::testing::Invoke; 38 using ::testing::Invoke;
41 using ::testing::NiceMock; 39 using ::testing::NiceMock;
42 using ::testing::NotNull; 40 using ::testing::NotNull;
43 using ::testing::Return; 41 using ::testing::Return;
44 using ::testing::TestWithParam;
45 42
46 // #define ENABLE_DEBUG_PRINTF 43 // #define ENABLE_DEBUG_PRINTF
47 #ifdef ENABLE_DEBUG_PRINTF 44 #ifdef ENABLE_DEBUG_PRINTF
48 #define PRINTD(...) fprintf(stderr, __VA_ARGS__); 45 #define PRINTD(...) fprintf(stderr, __VA_ARGS__);
49 #else 46 #else
50 #define PRINTD(...) ((void)0) 47 #define PRINTD(...) ((void)0)
51 #endif 48 #endif
52 #define PRINT(...) fprintf(stderr, __VA_ARGS__); 49 #define PRINT(...) fprintf(stderr, __VA_ARGS__);
53 50
54 namespace webrtc { 51 namespace webrtc {
55 52
56 // Number of callbacks (input or output) the tests waits for before we set 53 // Number of callbacks (input or output) the tests waits for before we set
57 // an event indicating that the test was OK. 54 // an event indicating that the test was OK.
58 static const int kNumCallbacks = 10; 55 static const int kNumCallbacks = 10;
59 // Max amount of time we wait for an event to be set while counting callbacks. 56 // Max amount of time we wait for an event to be set while counting callbacks.
60 static const int kTestTimeOutInMilliseconds = 10 * 1000; 57 static const int kTestTimeOutInMilliseconds = 10 * 1000;
58 // Number of bits per PCM audio sample.
59 static const int kBitsPerSample = 16;
60 // Number of bytes per PCM audio sample.
61 static const int kBytesPerSample = kBitsPerSample / 8;
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 int 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 = 15;
65 static const int kBitsPerSample = 16;
66 static const int kBytesPerSample = kBitsPerSample / 8;
67 // Run the full-duplex test during this time (unit is in seconds). 66 // Run the full-duplex test during this time (unit is in seconds).
68 // Note that first |kNumIgnoreFirstCallbacks| are ignored. 67 // Note that first |kNumIgnoreFirstCallbacks| are ignored.
69 static const int kFullDuplexTimeInSec = 5; 68 static const int kFullDuplexTimeInSec = 10;
70 // Wait for the callback sequence to stabilize by ignoring this amount of the 69 // Wait for the callback sequence to stabilize by ignoring this amount of the
71 // initial callbacks (avoids initial FIFO access). 70 // initial callbacks (avoids initial FIFO access).
72 // Only used in the RunPlayoutAndRecordingInFullDuplex test. 71 // Only used in the RunPlayoutAndRecordingInFullDuplex test.
73 static const int kNumIgnoreFirstCallbacks = 50; 72 static const int kNumIgnoreFirstCallbacks = 50;
74 // Sets the number of impulses per second in the latency test. 73 // Sets the number of impulses per second in the latency test.
74 // TODO(henrika): fine tune this setting for iOS.
75 static const int kImpulseFrequencyInHz = 1; 75 static const int kImpulseFrequencyInHz = 1;
76 // Length of round-trip latency measurements. Number of transmitted impulses 76 // Length of round-trip latency measurements. Number of transmitted impulses
77 // is kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1. 77 // is kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1.
78 static const int kMeasureLatencyTimeInSec = 11; 78 // TODO(henrika): fine tune this setting for iOS.
79 static const int kMeasureLatencyTimeInSec = 5;
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 // TODO(henrika): fine tune this setting for iOS.
82 static const int kImpulseThreshold = 50;
81 static const char kTag[] = "[..........] "; 83 static const char kTag[] = "[..........] ";
82 84
83 enum TransportType { 85 enum TransportType {
84 kPlayout = 0x1, 86 kPlayout = 0x1,
85 kRecording = 0x2, 87 kRecording = 0x2,
86 }; 88 };
87 89
88 // Interface for processing the audio stream. Real implementations can e.g. 90 // Interface for processing the audio stream. Real implementations can e.g.
89 // run audio in loopback, read audio from a file or perform latency 91 // run audio in loopback, read audio from a file or perform latency
90 // measurements. 92 // measurements.
91 class AudioStreamInterface { 93 class AudioStreamInterface {
92 public: 94 public:
93 virtual void Write(const void* source, int num_frames) = 0; 95 virtual void Write(const void* source, int num_frames) = 0;
94 virtual void Read(void* destination, int num_frames) = 0; 96 virtual void Read(void* destination, int num_frames) = 0;
97
95 protected: 98 protected:
96 virtual ~AudioStreamInterface() {} 99 virtual ~AudioStreamInterface() {}
97 }; 100 };
98 101
99 // Reads audio samples from a PCM file where the file is stored in memory at 102 // Reads audio samples from a PCM file where the file is stored in memory at
100 // construction. 103 // construction.
101 class FileAudioStream : public AudioStreamInterface { 104 class FileAudioStream : public AudioStreamInterface {
102 public: 105 public:
103 FileAudioStream( 106 FileAudioStream(int num_callbacks,
104 int num_callbacks, const std::string& file_name, int sample_rate) 107 const std::string& file_name,
105 : file_size_in_bytes_(0), 108 int sample_rate)
106 sample_rate_(sample_rate), 109 : file_size_in_bytes_(0), sample_rate_(sample_rate), file_pos_(0) {
107 file_pos_(0) {
108 file_size_in_bytes_ = test::GetFileSize(file_name); 110 file_size_in_bytes_ = test::GetFileSize(file_name);
109 sample_rate_ = sample_rate; 111 sample_rate_ = sample_rate;
110 EXPECT_GE(file_size_in_callbacks(), num_callbacks) 112 EXPECT_GE(file_size_in_callbacks(), num_callbacks)
111 << "Size of test file is not large enough to last during the test."; 113 << "Size of test file is not large enough to last during the test.";
112 const int num_16bit_samples = 114 const int num_16bit_samples =
113 test::GetFileSize(file_name) / kBytesPerSample; 115 test::GetFileSize(file_name) / kBytesPerSample;
114 file_.reset(new int16_t[num_16bit_samples]); 116 file_.reset(new int16_t[num_16bit_samples]);
115 FILE* audio_file = fopen(file_name.c_str(), "rb"); 117 FILE* audio_file = fopen(file_name.c_str(), "rb");
116 EXPECT_NE(audio_file, nullptr); 118 EXPECT_NE(audio_file, nullptr);
117 int num_samples_read = fread( 119 int num_samples_read =
118 file_.get(), sizeof(int16_t), num_16bit_samples, audio_file); 120 fread(file_.get(), sizeof(int16_t), num_16bit_samples, audio_file);
119 EXPECT_EQ(num_samples_read, num_16bit_samples); 121 EXPECT_EQ(num_samples_read, num_16bit_samples);
120 fclose(audio_file); 122 fclose(audio_file);
121 } 123 }
122 124
123 // AudioStreamInterface::Write() is not implemented. 125 // AudioStreamInterface::Write() is not implemented.
124 void Write(const void* source, int num_frames) override {} 126 void Write(const void* source, int num_frames) override {}
125 127
126 // Read samples from file stored in memory (at construction) and copy 128 // Read samples from file stored in memory (at construction) and copy
127 // |num_frames| (<=> 10ms) to the |destination| byte buffer. 129 // |num_frames| (<=> 10ms) to the |destination| byte buffer.
128 void Read(void* destination, int num_frames) override { 130 void Read(void* destination, int num_frames) override {
129 memcpy(destination, 131 memcpy(destination, static_cast<int16_t*>(&file_[file_pos_]),
130 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 (file_size_in_bytes_ / (kBytesPerSample * sample_rate_));
137 } 138 }
138 int file_size_in_callbacks() const { 139 int file_size_in_callbacks() const {
139 return file_size_in_seconds() * kNumCallbacksPerSecond; 140 return file_size_in_seconds() * kNumCallbacksPerSecond;
140 } 141 }
(...skipping 18 matching lines...) Expand all
159 explicit FifoAudioStream(int frames_per_buffer) 160 explicit FifoAudioStream(int frames_per_buffer)
160 : frames_per_buffer_(frames_per_buffer), 161 : frames_per_buffer_(frames_per_buffer),
161 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)), 162 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
162 fifo_(new AudioBufferList), 163 fifo_(new AudioBufferList),
163 largest_size_(0), 164 largest_size_(0),
164 total_written_elements_(0), 165 total_written_elements_(0),
165 write_count_(0) { 166 write_count_(0) {
166 EXPECT_NE(fifo_.get(), nullptr); 167 EXPECT_NE(fifo_.get(), nullptr);
167 } 168 }
168 169
169 ~FifoAudioStream() { 170 ~FifoAudioStream() { Flush(); }
170 Flush();
171 }
172 171
173 // Allocate new memory, copy |num_frames| samples from |source| into memory 172 // Allocate new memory, copy |num_frames| samples from |source| into memory
174 // and add pointer to the memory location to end of the list. 173 // and add pointer to the memory location to end of the list.
175 // Increases the size of the FIFO by one element. 174 // Increases the size of the FIFO by one element.
176 void Write(const void* source, int num_frames) override { 175 void Write(const void* source, int num_frames) override {
177 ASSERT_EQ(num_frames, frames_per_buffer_); 176 ASSERT_EQ(num_frames, frames_per_buffer_);
178 PRINTD("+"); 177 PRINTD("+");
179 if (write_count_++ < kNumIgnoreFirstCallbacks) { 178 if (write_count_++ < kNumIgnoreFirstCallbacks) {
180 return; 179 return;
181 } 180 }
182 int16_t* memory = new int16_t[frames_per_buffer_]; 181 int16_t* memory = new int16_t[frames_per_buffer_];
183 memcpy(static_cast<int16_t*> (&memory[0]), 182 memcpy(static_cast<int16_t*>(&memory[0]), source, bytes_per_buffer_);
184 source,
185 bytes_per_buffer_);
186 rtc::CritScope lock(&lock_); 183 rtc::CritScope lock(&lock_);
187 fifo_->push_back(memory); 184 fifo_->push_back(memory);
188 const int size = fifo_->size(); 185 const int size = fifo_->size();
189 if (size > largest_size_) { 186 if (size > largest_size_) {
190 largest_size_ = size; 187 largest_size_ = size;
191 PRINTD("(%d)", largest_size_); 188 PRINTD("(%d)", largest_size_);
192 } 189 }
193 total_written_elements_ += size; 190 total_written_elements_ += size;
194 } 191 }
195 192
196 // Read pointer to data buffer from front of list, copy |num_frames| of stored 193 // Read pointer to data buffer from front of list, copy |num_frames| of stored
197 // data into |destination| and delete the utilized memory allocation. 194 // data into |destination| and delete the utilized memory allocation.
198 // Decreases the size of the FIFO by one element. 195 // Decreases the size of the FIFO by one element.
199 void Read(void* destination, int num_frames) override { 196 void Read(void* destination, int num_frames) override {
200 ASSERT_EQ(num_frames, frames_per_buffer_); 197 ASSERT_EQ(num_frames, frames_per_buffer_);
201 PRINTD("-"); 198 PRINTD("-");
202 rtc::CritScope lock(&lock_); 199 rtc::CritScope lock(&lock_);
203 if (fifo_->empty()) { 200 if (fifo_->empty()) {
204 memset(destination, 0, bytes_per_buffer_); 201 memset(destination, 0, bytes_per_buffer_);
205 } else { 202 } else {
206 int16_t* memory = fifo_->front(); 203 int16_t* memory = fifo_->front();
207 fifo_->pop_front(); 204 fifo_->pop_front();
208 memcpy(destination, 205 memcpy(destination, static_cast<int16_t*>(&memory[0]), bytes_per_buffer_);
209 static_cast<int16_t*> (&memory[0]),
210 bytes_per_buffer_);
211 delete memory; 206 delete memory;
212 } 207 }
213 } 208 }
214 209
215 int size() const { 210 int size() const { return fifo_->size(); }
216 return fifo_->size();
217 }
218 211
219 int largest_size() const { 212 int largest_size() const { return largest_size_; }
220 return largest_size_;
221 }
222 213
223 int average_size() const { 214 int average_size() const {
224 return (total_written_elements_ == 0) ? 0.0 : 0.5 + static_cast<float> ( 215 return (total_written_elements_ == 0)
225 total_written_elements_) / (write_count_ - kNumIgnoreFirstCallbacks); 216 ? 0.0
217 : 0.5 +
218 static_cast<float>(total_written_elements_) /
219 (write_count_ - kNumIgnoreFirstCallbacks);
226 } 220 }
227 221
228 private: 222 private:
229 void Flush() { 223 void Flush() {
230 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) { 224 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) {
231 delete *it; 225 delete *it;
232 } 226 }
233 fifo_->clear(); 227 fifo_->clear();
234 } 228 }
235 229
(...skipping 12 matching lines...) Expand all
248 // Usage requires a special hardware called Audio Loopback Dongle. 242 // Usage requires a special hardware called Audio Loopback Dongle.
249 // See http://source.android.com/devices/audio/loopback.html for details. 243 // See http://source.android.com/devices/audio/loopback.html for details.
250 class LatencyMeasuringAudioStream : public AudioStreamInterface { 244 class LatencyMeasuringAudioStream : public AudioStreamInterface {
251 public: 245 public:
252 explicit LatencyMeasuringAudioStream(int frames_per_buffer) 246 explicit LatencyMeasuringAudioStream(int frames_per_buffer)
253 : clock_(Clock::GetRealTimeClock()), 247 : clock_(Clock::GetRealTimeClock()),
254 frames_per_buffer_(frames_per_buffer), 248 frames_per_buffer_(frames_per_buffer),
255 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)), 249 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
256 play_count_(0), 250 play_count_(0),
257 rec_count_(0), 251 rec_count_(0),
258 pulse_time_(0) { 252 pulse_time_(0) {}
259 }
260 253
261 // Insert periodic impulses in first two samples of |destination|. 254 // Insert periodic impulses in first two samples of |destination|.
262 void Read(void* destination, int num_frames) override { 255 void Read(void* destination, int num_frames) override {
263 ASSERT_EQ(num_frames, frames_per_buffer_); 256 ASSERT_EQ(num_frames, frames_per_buffer_);
264 if (play_count_ == 0) { 257 if (play_count_ == 0) {
265 PRINT("["); 258 PRINT("[");
266 } 259 }
267 play_count_++; 260 play_count_++;
268 memset(destination, 0, bytes_per_buffer_); 261 memset(destination, 0, bytes_per_buffer_);
269 if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) { 262 if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) {
270 if (pulse_time_ == 0) { 263 if (pulse_time_ == 0) {
271 pulse_time_ = clock_->TimeInMilliseconds(); 264 pulse_time_ = clock_->TimeInMilliseconds();
272 } 265 }
273 PRINT("."); 266 PRINT(".");
274 const int16_t impulse = std::numeric_limits<int16_t>::max(); 267 const int16_t impulse = std::numeric_limits<int16_t>::max();
275 int16_t* ptr16 = static_cast<int16_t*> (destination); 268 int16_t* ptr16 = static_cast<int16_t*>(destination);
276 for (int i = 0; i < 2; ++i) { 269 for (int i = 0; i < 2; ++i) {
277 *ptr16++ = impulse; 270 *ptr16++ = impulse;
278 } 271 }
279 } 272 }
280 } 273 }
281 274
282 // Detect received impulses in |source|, derive time between transmission and 275 // Detect received impulses in |source|, derive time between transmission and
283 // detection and add the calculated delay to list of latencies. 276 // detection and add the calculated delay to list of latencies.
284 void Write(const void* source, int num_frames) override { 277 void Write(const void* source, int num_frames) override {
285 ASSERT_EQ(num_frames, frames_per_buffer_); 278 ASSERT_EQ(num_frames, frames_per_buffer_);
286 rec_count_++; 279 rec_count_++;
287 if (pulse_time_ == 0) { 280 if (pulse_time_ == 0) {
288 // Avoid detection of new impulse response until a new impulse has 281 // Avoid detection of new impulse response until a new impulse has
289 // been transmitted (sets |pulse_time_| to value larger than zero). 282 // been transmitted (sets |pulse_time_| to value larger than zero).
290 return; 283 return;
291 } 284 }
292 const int16_t* ptr16 = static_cast<const int16_t*> (source); 285 const int16_t* ptr16 = static_cast<const int16_t*>(source);
293 std::vector<int16_t> vec(ptr16, ptr16 + num_frames); 286 std::vector<int16_t> vec(ptr16, ptr16 + num_frames);
294 // Find max value in the audio buffer. 287 // Find max value in the audio buffer.
295 int max = *std::max_element(vec.begin(), vec.end()); 288 int max = *std::max_element(vec.begin(), vec.end());
296 // Find index (element position in vector) of the max element. 289 // Find index (element position in vector) of the max element.
297 int index_of_max = std::distance(vec.begin(), 290 int index_of_max =
298 std::find(vec.begin(), vec.end(), 291 std::distance(vec.begin(), std::find(vec.begin(), vec.end(), max));
299 max));
300 if (max > kImpulseThreshold) { 292 if (max > kImpulseThreshold) {
301 PRINTD("(%d,%d)", max, index_of_max); 293 PRINTD("(%d,%d)", max, index_of_max);
302 int64_t now_time = clock_->TimeInMilliseconds(); 294 int64_t now_time = clock_->TimeInMilliseconds();
303 int extra_delay = IndexToMilliseconds(static_cast<double> (index_of_max)); 295 int extra_delay = IndexToMilliseconds(static_cast<double>(index_of_max));
304 PRINTD("[%d]", static_cast<int> (now_time - pulse_time_)); 296 PRINTD("[%d]", static_cast<int>(now_time - pulse_time_));
305 PRINTD("[%d]", extra_delay); 297 PRINTD("[%d]", extra_delay);
306 // Total latency is the difference between transmit time and detection 298 // Total latency is the difference between transmit time and detection
307 // tome plus the extra delay within the buffer in which we detected the 299 // tome plus the extra delay within the buffer in which we detected the
308 // received impulse. It is transmitted at sample 0 but can be received 300 // 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 301 // at sample N where N > 0. The term |extra_delay| accounts for N and it
310 // is a value between 0 and 10ms. 302 // is a value between 0 and 10ms.
311 latencies_.push_back(now_time - pulse_time_ + extra_delay); 303 latencies_.push_back(now_time - pulse_time_ + extra_delay);
312 pulse_time_ = 0; 304 pulse_time_ = 0;
313 } else { 305 } else {
314 PRINTD("-"); 306 PRINTD("-");
315 } 307 }
316 } 308 }
317 309
318 int num_latency_values() const { 310 int num_latency_values() const { return latencies_.size(); }
319 return latencies_.size();
320 }
321 311
322 int min_latency() const { 312 int min_latency() const {
323 if (latencies_.empty()) 313 if (latencies_.empty())
324 return 0; 314 return 0;
325 return *std::min_element(latencies_.begin(), latencies_.end()); 315 return *std::min_element(latencies_.begin(), latencies_.end());
326 } 316 }
327 317
328 int max_latency() const { 318 int max_latency() const {
329 if (latencies_.empty()) 319 if (latencies_.empty())
330 return 0; 320 return 0;
331 return *std::max_element(latencies_.begin(), latencies_.end()); 321 return *std::max_element(latencies_.begin(), latencies_.end());
332 } 322 }
333 323
334 int average_latency() const { 324 int average_latency() const {
335 if (latencies_.empty()) 325 if (latencies_.empty())
336 return 0; 326 return 0;
337 return 0.5 + static_cast<double> ( 327 return 0.5 +
338 std::accumulate(latencies_.begin(), latencies_.end(), 0)) / 328 static_cast<double>(
339 latencies_.size(); 329 std::accumulate(latencies_.begin(), latencies_.end(), 0)) /
330 latencies_.size();
340 } 331 }
341 332
342 void PrintResults() const { 333 void PrintResults() const {
343 PRINT("] "); 334 PRINT("] ");
344 for (auto it = latencies_.begin(); it != latencies_.end(); ++it) { 335 for (auto it = latencies_.begin(); it != latencies_.end(); ++it) {
345 PRINT("%d ", *it); 336 PRINT("%d ", *it);
346 } 337 }
347 PRINT("\n"); 338 PRINT("\n");
348 PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag, 339 PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag, min_latency(),
349 min_latency(), max_latency(), average_latency()); 340 max_latency(), average_latency());
350 } 341 }
351 342
352 int IndexToMilliseconds(double index) const { 343 int IndexToMilliseconds(double index) const {
353 return 10.0 * (index / frames_per_buffer_) + 0.5; 344 return 10.0 * (index / frames_per_buffer_) + 0.5;
354 } 345 }
355 346
356 private: 347 private:
357 Clock* clock_; 348 Clock* clock_;
358 const int frames_per_buffer_; 349 const int frames_per_buffer_;
359 const int bytes_per_buffer_; 350 const int bytes_per_buffer_;
360 int play_count_; 351 int play_count_;
361 int rec_count_; 352 int rec_count_;
362 int64_t pulse_time_; 353 int64_t pulse_time_;
363 std::vector<int> latencies_; 354 std::vector<int> latencies_;
364 }; 355 };
365
366 // Mocks the AudioTransport object and proxies actions for the two callbacks 356 // Mocks the AudioTransport object and proxies actions for the two callbacks
367 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations 357 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations
368 // of AudioStreamInterface. 358 // of AudioStreamInterface.
369 class MockAudioTransport : public AudioTransport { 359 class MockAudioTransport : public AudioTransport {
370 public: 360 public:
371 explicit MockAudioTransport(int type) 361 explicit MockAudioTransport(int type)
372 : num_callbacks_(0), 362 : num_callbacks_(0),
373 type_(type), 363 type_(type),
374 play_count_(0), 364 play_count_(0),
375 rec_count_(0), 365 rec_count_(0),
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 bool play_mode() const { return type_ & kPlayout; } 472 bool play_mode() const { return type_ & kPlayout; }
483 bool rec_mode() const { return type_ & kRecording; } 473 bool rec_mode() const { return type_ & kRecording; }
484 474
485 private: 475 private:
486 EventWrapper* test_is_done_; 476 EventWrapper* test_is_done_;
487 int num_callbacks_; 477 int num_callbacks_;
488 int type_; 478 int type_;
489 int play_count_; 479 int play_count_;
490 int rec_count_; 480 int rec_count_;
491 AudioStreamInterface* audio_stream_; 481 AudioStreamInterface* audio_stream_;
492 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream_;
493 }; 482 };
494 483
495 // AudioDeviceTest test fixture. 484 // AudioDeviceTest test fixture.
496 class AudioDeviceTest : public ::testing::Test { 485 class AudioDeviceTest : public ::testing::Test {
497 protected: 486 protected:
498 AudioDeviceTest() 487 AudioDeviceTest() : test_is_done_(EventWrapper::Create()) {
499 : test_is_done_(EventWrapper::Create()) { 488 old_sev_ = rtc::LogMessage::GetLogToDebug();
500 // One-time initialization of JVM and application context. Ensures that we 489 // Set suitable logging level here. Change to rtc::LS_INFO for more verbose
501 // can do calls between C++ and Java. Initializes both Java and OpenSL ES 490 // output. See webrtc/base/logging.h for complete list of options.
502 // implementations. 491 rtc::LogMessage::LogToDebug(rtc::LS_INFO);
503 webrtc::audiodevicemodule::EnsureInitialized(); 492 // Add extra logging fields here (timestamps and thread id).
493 // rtc::LogMessage::LogTimestamps();
494 rtc::LogMessage::LogThreads();
504 // Creates an audio device using a default audio layer. 495 // Creates an audio device using a default audio layer.
505 audio_device_ = CreateAudioDevice(AudioDeviceModule::kPlatformDefaultAudio); 496 audio_device_ = CreateAudioDevice(AudioDeviceModule::kPlatformDefaultAudio);
506 EXPECT_NE(audio_device_.get(), nullptr); 497 EXPECT_NE(audio_device_.get(), nullptr);
507 EXPECT_EQ(0, audio_device_->Init()); 498 EXPECT_EQ(0, audio_device_->Init());
508 playout_parameters_ = audio_manager()->GetPlayoutAudioParameters(); 499 EXPECT_EQ(0,
509 record_parameters_ = audio_manager()->GetRecordAudioParameters(); 500 audio_device()->GetPlayoutAudioParameters(&playout_parameters_));
510 build_info_.reset(new BuildInfo()); 501 EXPECT_EQ(0, audio_device()->GetRecordAudioParameters(&record_parameters_));
511 } 502 }
512 virtual ~AudioDeviceTest() { 503 virtual ~AudioDeviceTest() {
513 EXPECT_EQ(0, audio_device_->Terminate()); 504 EXPECT_EQ(0, audio_device_->Terminate());
505 rtc::LogMessage::LogToDebug(old_sev_);
514 } 506 }
515 507
516 int playout_sample_rate() const { 508 // TODO(henrika): don't use hardcoded values below.
517 return playout_parameters_.sample_rate(); 509 int playout_sample_rate() const { return playout_parameters_.sample_rate(); }
518 } 510 int record_sample_rate() const { return record_parameters_.sample_rate(); }
519 int record_sample_rate() const { 511 int playout_channels() const { return playout_parameters_.channels(); }
520 return record_parameters_.sample_rate(); 512 int record_channels() const { return record_parameters_.channels(); }
521 }
522 int playout_channels() const {
523 return playout_parameters_.channels();
524 }
525 int record_channels() const {
526 return record_parameters_.channels();
527 }
528 int playout_frames_per_10ms_buffer() const { 513 int playout_frames_per_10ms_buffer() const {
529 return playout_parameters_.frames_per_10ms_buffer(); 514 return playout_parameters_.frames_per_10ms_buffer();
530 } 515 }
531 int record_frames_per_10ms_buffer() const { 516 int record_frames_per_10ms_buffer() const {
532 return record_parameters_.frames_per_10ms_buffer(); 517 return record_parameters_.frames_per_10ms_buffer();
533 } 518 }
534 519
535 int total_delay_ms() const { 520 int total_delay_ms() const {
536 return audio_manager()->GetDelayEstimateInMilliseconds(); 521 // TODO(henrika): improve this part.
522 return 100;
537 } 523 }
538 524
539 rtc::scoped_refptr<AudioDeviceModule> audio_device() const { 525 rtc::scoped_refptr<AudioDeviceModule> audio_device() const {
540 return audio_device_; 526 return audio_device_;
541 } 527 }
542 528
543 AudioDeviceModuleImpl* audio_device_impl() const { 529 AudioDeviceModuleImpl* audio_device_impl() const {
544 return static_cast<AudioDeviceModuleImpl*>(audio_device_.get()); 530 return static_cast<AudioDeviceModuleImpl*>(audio_device_.get());
545 } 531 }
546 532
547 AudioManager* audio_manager() const {
548 return audio_device_impl()->GetAndroidAudioManagerForTest();
549 }
550
551 AudioManager* GetAudioManager(AudioDeviceModule* adm) const {
552 return static_cast<AudioDeviceModuleImpl*>(adm)->
553 GetAndroidAudioManagerForTest();
554 }
555
556 AudioDeviceBuffer* audio_device_buffer() const { 533 AudioDeviceBuffer* audio_device_buffer() const {
557 return audio_device_impl()->GetAudioDeviceBuffer(); 534 return audio_device_impl()->GetAudioDeviceBuffer();
558 } 535 }
559 536
560 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDevice( 537 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDevice(
561 AudioDeviceModule::AudioLayer audio_layer) { 538 AudioDeviceModule::AudioLayer audio_layer) {
562 rtc::scoped_refptr<AudioDeviceModule> module( 539 rtc::scoped_refptr<AudioDeviceModule> module(
563 AudioDeviceModuleImpl::Create(0, audio_layer)); 540 AudioDeviceModuleImpl::Create(0, audio_layer));
564 return module; 541 return module;
565 } 542 }
566 543
567 // Returns file name relative to the resource root given a sample rate. 544 // Returns file name relative to the resource root given a sample rate.
568 std::string GetFileName(int sample_rate) { 545 std::string GetFileName(int sample_rate) {
569 EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100); 546 EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100 ||
547 sample_rate == 16000);
570 char fname[64]; 548 char fname[64];
571 snprintf(fname, 549 snprintf(fname, sizeof(fname), "audio_device/audio_short%d",
572 sizeof(fname),
573 "audio_device/audio_short%d",
574 sample_rate / 1000); 550 sample_rate / 1000);
575 std::string file_name(webrtc::test::ResourcePath(fname, "pcm")); 551 std::string file_name(webrtc::test::ResourcePath(fname, "pcm"));
576 EXPECT_TRUE(test::FileExists(file_name)); 552 EXPECT_TRUE(test::FileExists(file_name));
577 #ifdef ENABLE_PRINTF 553 #ifdef ENABLE_DEBUG_PRINTF
578 PRINT("file name: %s\n", file_name.c_str()); 554 PRINTD("file name: %s\n", file_name.c_str());
579 const int bytes = test::GetFileSize(file_name); 555 const int bytes = test::GetFileSize(file_name);
580 PRINT("file size: %d [bytes]\n", bytes); 556 PRINTD("file size: %d [bytes]\n", bytes);
581 PRINT("file size: %d [samples]\n", bytes / kBytesPerSample); 557 PRINTD("file size: %d [samples]\n", bytes / kBytesPerSample);
582 const int seconds = bytes / (sample_rate * kBytesPerSample); 558 const int seconds = bytes / (sample_rate * kBytesPerSample);
583 PRINT("file size: %d [secs]\n", seconds); 559 PRINTD("file size: %d [secs]\n", seconds);
584 PRINT("file size: %d [callbacks]\n", seconds * kNumCallbacksPerSecond); 560 PRINTD("file size: %d [callbacks]\n", seconds * kNumCallbacksPerSecond);
585 #endif 561 #endif
586 return file_name; 562 return file_name;
587 } 563 }
588 564
589 AudioDeviceModule::AudioLayer GetActiveAudioLayer() const {
590 AudioDeviceModule::AudioLayer audio_layer;
591 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer));
592 return audio_layer;
593 }
594
595 int TestDelayOnAudioLayer(
596 const AudioDeviceModule::AudioLayer& layer_to_test) {
597 rtc::scoped_refptr<AudioDeviceModule> audio_device;
598 audio_device = CreateAudioDevice(layer_to_test);
599 EXPECT_NE(audio_device.get(), nullptr);
600 AudioManager* audio_manager = GetAudioManager(audio_device.get());
601 EXPECT_NE(audio_manager, nullptr);
602 return audio_manager->GetDelayEstimateInMilliseconds();
603 }
604
605 AudioDeviceModule::AudioLayer TestActiveAudioLayer(
606 const AudioDeviceModule::AudioLayer& layer_to_test) {
607 rtc::scoped_refptr<AudioDeviceModule> audio_device;
608 audio_device = CreateAudioDevice(layer_to_test);
609 EXPECT_NE(audio_device.get(), nullptr);
610 AudioDeviceModule::AudioLayer active;
611 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&active));
612 return active;
613 }
614
615 bool DisableTestForThisDevice(const std::string& model) {
616 return (build_info_->GetDeviceModel() == model);
617 }
618
619 // Volume control is currently only supported for the Java output audio layer.
620 // For OpenSL ES, the internal stream volume is always on max level and there
621 // is no need for this test to set it to max.
622 bool AudioLayerSupportsVolumeControl() const {
623 return GetActiveAudioLayer() == AudioDeviceModule::kAndroidJavaAudio;
624 }
625
626 void SetMaxPlayoutVolume() {
627 if (!AudioLayerSupportsVolumeControl())
628 return;
629 uint32_t max_volume;
630 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume));
631 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume));
632 }
633
634 void DisableBuiltInAECIfAvailable() {
635 if (audio_device()->BuiltInAECIsAvailable()) {
636 EXPECT_EQ(0, audio_device()->EnableBuiltInAEC(false));
637 }
638 }
639
640 void StartPlayout() { 565 void StartPlayout() {
641 EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 566 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
642 EXPECT_FALSE(audio_device()->Playing()); 567 EXPECT_FALSE(audio_device()->Playing());
643 EXPECT_EQ(0, audio_device()->InitPlayout()); 568 EXPECT_EQ(0, audio_device()->InitPlayout());
644 EXPECT_TRUE(audio_device()->PlayoutIsInitialized()); 569 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
645 EXPECT_EQ(0, audio_device()->StartPlayout()); 570 EXPECT_EQ(0, audio_device()->StartPlayout());
646 EXPECT_TRUE(audio_device()->Playing()); 571 EXPECT_TRUE(audio_device()->Playing());
647 } 572 }
648 573
649 void StopPlayout() { 574 void StopPlayout() {
650 EXPECT_EQ(0, audio_device()->StopPlayout()); 575 EXPECT_EQ(0, audio_device()->StopPlayout());
651 EXPECT_FALSE(audio_device()->Playing()); 576 EXPECT_FALSE(audio_device()->Playing());
652 EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 577 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
653 } 578 }
654 579
655 void StartRecording() { 580 void StartRecording() {
656 EXPECT_FALSE(audio_device()->RecordingIsInitialized()); 581 EXPECT_FALSE(audio_device()->RecordingIsInitialized());
657 EXPECT_FALSE(audio_device()->Recording()); 582 EXPECT_FALSE(audio_device()->Recording());
658 EXPECT_EQ(0, audio_device()->InitRecording()); 583 EXPECT_EQ(0, audio_device()->InitRecording());
659 EXPECT_TRUE(audio_device()->RecordingIsInitialized()); 584 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
660 EXPECT_EQ(0, audio_device()->StartRecording()); 585 EXPECT_EQ(0, audio_device()->StartRecording());
661 EXPECT_TRUE(audio_device()->Recording()); 586 EXPECT_TRUE(audio_device()->Recording());
662 } 587 }
663 588
664 void StopRecording() { 589 void StopRecording() {
665 EXPECT_EQ(0, audio_device()->StopRecording()); 590 EXPECT_EQ(0, audio_device()->StopRecording());
666 EXPECT_FALSE(audio_device()->Recording()); 591 EXPECT_FALSE(audio_device()->Recording());
667 } 592 }
668 593
669 int GetMaxSpeakerVolume() const {
670 uint32_t max_volume(0);
671 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume));
672 return max_volume;
673 }
674
675 int GetMinSpeakerVolume() const {
676 uint32_t min_volume(0);
677 EXPECT_EQ(0, audio_device()->MinSpeakerVolume(&min_volume));
678 return min_volume;
679 }
680
681 int GetSpeakerVolume() const {
682 uint32_t volume(0);
683 EXPECT_EQ(0, audio_device()->SpeakerVolume(&volume));
684 return volume;
685 }
686
687 rtc::scoped_ptr<EventWrapper> test_is_done_; 594 rtc::scoped_ptr<EventWrapper> test_is_done_;
688 rtc::scoped_refptr<AudioDeviceModule> audio_device_; 595 rtc::scoped_refptr<AudioDeviceModule> audio_device_;
689 AudioParameters playout_parameters_; 596 AudioParameters playout_parameters_;
690 AudioParameters record_parameters_; 597 AudioParameters record_parameters_;
691 rtc::scoped_ptr<BuildInfo> build_info_; 598 rtc::LoggingSeverity old_sev_;
692 }; 599 };
693 600
694 TEST_F(AudioDeviceTest, ConstructDestruct) { 601 TEST_F(AudioDeviceTest, ConstructDestruct) {
695 // Using the test fixture to create and destruct the audio device module. 602 // Using the test fixture to create and destruct the audio device module.
696 } 603 }
697 604
698 // We always ask for a default audio layer when the ADM is constructed. But the
699 // ADM will then internally set the best suitable combination of audio layers,
700 // for input and output based on if low-latency output audio in combination
701 // with OpenSL ES is supported or not. This test ensures that the correct
702 // selection is done.
703 TEST_F(AudioDeviceTest, VerifyDefaultAudioLayer) {
704 const AudioDeviceModule::AudioLayer audio_layer = GetActiveAudioLayer();
705 bool low_latency_output = audio_manager()->IsLowLatencyPlayoutSupported();
706 AudioDeviceModule::AudioLayer expected_audio_layer = low_latency_output ?
707 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio :
708 AudioDeviceModule::kAndroidJavaAudio;
709 EXPECT_EQ(expected_audio_layer, audio_layer);
710 }
711
712 // Verify that it is possible to explicitly create the two types of supported
713 // ADMs. These two tests overrides the default selection of native audio layer
714 // by ignoring if the device supports low-latency output or not.
715 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo) {
716 AudioDeviceModule::AudioLayer expected_layer =
717 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio;
718 AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer(
719 expected_layer);
720 EXPECT_EQ(expected_layer, active_layer);
721 }
722
723 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForJavaInBothDirections) {
724 AudioDeviceModule::AudioLayer expected_layer =
725 AudioDeviceModule::kAndroidJavaAudio;
726 AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer(
727 expected_layer);
728 EXPECT_EQ(expected_layer, active_layer);
729 }
730
731 // The Android ADM supports two different delay reporting modes. One for the
732 // low-latency output path (in combination with OpenSL ES), and one for the
733 // high-latency output path (Java backends in both directions). These two tests
734 // verifies that the audio manager reports correct delay estimate given the
735 // selected audio layer. Note that, this delay estimate will only be utilized
736 // if the HW AEC is disabled.
737 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForHighLatencyOutputPath) {
738 EXPECT_EQ(kHighLatencyModeDelayEstimateInMilliseconds,
739 TestDelayOnAudioLayer(AudioDeviceModule::kAndroidJavaAudio));
740 }
741
742 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForLowLatencyOutputPath) {
743 EXPECT_EQ(kLowLatencyModeDelayEstimateInMilliseconds,
744 TestDelayOnAudioLayer(
745 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio));
746 }
747
748 // Ensure that the ADM internal audio device buffer is configured to use the
749 // correct set of parameters.
750 TEST_F(AudioDeviceTest, VerifyAudioDeviceBufferParameters) {
751 EXPECT_EQ(playout_parameters_.sample_rate(),
752 audio_device_buffer()->PlayoutSampleRate());
753 EXPECT_EQ(record_parameters_.sample_rate(),
754 audio_device_buffer()->RecordingSampleRate());
755 EXPECT_EQ(playout_parameters_.channels(),
756 audio_device_buffer()->PlayoutChannels());
757 EXPECT_EQ(record_parameters_.channels(),
758 audio_device_buffer()->RecordingChannels());
759 }
760
761
762 TEST_F(AudioDeviceTest, InitTerminate) { 605 TEST_F(AudioDeviceTest, InitTerminate) {
763 // Initialization is part of the test fixture. 606 // Initialization is part of the test fixture.
764 EXPECT_TRUE(audio_device()->Initialized()); 607 EXPECT_TRUE(audio_device()->Initialized());
608 // webrtc::SleepMs(5 * 1000);
765 EXPECT_EQ(0, audio_device()->Terminate()); 609 EXPECT_EQ(0, audio_device()->Terminate());
766 EXPECT_FALSE(audio_device()->Initialized()); 610 EXPECT_FALSE(audio_device()->Initialized());
767 } 611 }
768 612
769 TEST_F(AudioDeviceTest, Devices) {
770 // Device enumeration is not supported. Verify fixed values only.
771 EXPECT_EQ(1, audio_device()->PlayoutDevices());
772 EXPECT_EQ(1, audio_device()->RecordingDevices());
773 }
774
775 TEST_F(AudioDeviceTest, SpeakerVolumeShouldBeAvailable) {
776 // The OpenSL ES output audio path does not support volume control.
777 if (!AudioLayerSupportsVolumeControl())
778 return;
779 bool available;
780 EXPECT_EQ(0, audio_device()->SpeakerVolumeIsAvailable(&available));
781 EXPECT_TRUE(available);
782 }
783
784 TEST_F(AudioDeviceTest, MaxSpeakerVolumeIsPositive) {
785 // The OpenSL ES output audio path does not support volume control.
786 if (!AudioLayerSupportsVolumeControl())
787 return;
788 StartPlayout();
789 EXPECT_GT(GetMaxSpeakerVolume(), 0);
790 StopPlayout();
791 }
792
793 TEST_F(AudioDeviceTest, MinSpeakerVolumeIsZero) {
794 // The OpenSL ES output audio path does not support volume control.
795 if (!AudioLayerSupportsVolumeControl())
796 return;
797 EXPECT_EQ(GetMinSpeakerVolume(), 0);
798 }
799
800 TEST_F(AudioDeviceTest, DefaultSpeakerVolumeIsWithinMinMax) {
801 // The OpenSL ES output audio path does not support volume control.
802 if (!AudioLayerSupportsVolumeControl())
803 return;
804 const int default_volume = GetSpeakerVolume();
805 EXPECT_GE(default_volume, GetMinSpeakerVolume());
806 EXPECT_LE(default_volume, GetMaxSpeakerVolume());
807 }
808
809 TEST_F(AudioDeviceTest, SetSpeakerVolumeActuallySetsVolume) {
810 // The OpenSL ES output audio path does not support volume control.
811 if (!AudioLayerSupportsVolumeControl())
812 return;
813 const int default_volume = GetSpeakerVolume();
814 const int max_volume = GetMaxSpeakerVolume();
815 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume));
816 int new_volume = GetSpeakerVolume();
817 EXPECT_EQ(new_volume, max_volume);
818 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(default_volume));
819 }
820
821 // Tests that playout can be initiated, started and stopped. No audio callback 613 // Tests that playout can be initiated, started and stopped. No audio callback
822 // is registered in this test. 614 // is registered in this test.
823 TEST_F(AudioDeviceTest, StartStopPlayout) { 615 TEST_F(AudioDeviceTest, StartStopPlayout) {
824 StartPlayout(); 616 StartPlayout();
825 StopPlayout(); 617 StopPlayout();
826 StartPlayout(); 618 StartPlayout();
827 StopPlayout(); 619 StopPlayout();
828 } 620 }
829 621
622 // Tests that recording can be initiated, started and stopped. No audio callback
623 // is registered in this test.
624 TEST_F(AudioDeviceTest, StartStopRecording) {
625 StartRecording();
626 StopRecording();
627 StartRecording();
628 StopRecording();
629 }
630
830 // Verify that calling StopPlayout() will leave us in an uninitialized state 631 // Verify that calling StopPlayout() will leave us in an uninitialized state
831 // which will require a new call to InitPlayout(). This test does not call 632 // which will require a new call to InitPlayout(). This test does not call
832 // StartPlayout() while being uninitialized since doing so will hit a DCHECK. 633 // StartPlayout() while being uninitialized since doing so will hit a DCHECK.
833 TEST_F(AudioDeviceTest, StopPlayoutRequiresInitToRestart) { 634 TEST_F(AudioDeviceTest, StopPlayoutRequiresInitToRestart) {
834 EXPECT_EQ(0, audio_device()->InitPlayout()); 635 EXPECT_EQ(0, audio_device()->InitPlayout());
835 EXPECT_EQ(0, audio_device()->StartPlayout()); 636 EXPECT_EQ(0, audio_device()->StartPlayout());
836 EXPECT_EQ(0, audio_device()->StopPlayout()); 637 EXPECT_EQ(0, audio_device()->StopPlayout());
837 EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 638 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
838 } 639 }
839 640
840 // Start playout and verify that the native audio layer starts asking for real 641 // Start playout and verify that the native audio layer starts asking for real
841 // audio samples to play out using the NeedMorePlayData callback. 642 // audio samples to play out using the NeedMorePlayData callback.
842 TEST_F(AudioDeviceTest, StartPlayoutVerifyCallbacks) { 643 TEST_F(AudioDeviceTest, StartPlayoutVerifyCallbacks) {
843 MockAudioTransport mock(kPlayout); 644 MockAudioTransport mock(kPlayout);
844 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 645 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
845 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(), 646 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(),
846 kBytesPerSample, 647 kBytesPerSample, playout_channels(),
847 playout_channels(), 648 playout_sample_rate(), NotNull(), _, _, _))
848 playout_sample_rate(),
849 NotNull(),
850 _, _, _))
851 .Times(AtLeast(kNumCallbacks)); 649 .Times(AtLeast(kNumCallbacks));
852 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 650 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
853 StartPlayout(); 651 StartPlayout();
854 test_is_done_->Wait(kTestTimeOutInMilliseconds); 652 test_is_done_->Wait(kTestTimeOutInMilliseconds);
855 StopPlayout(); 653 StopPlayout();
856 } 654 }
857 655
858 // Start recording and verify that the native audio layer starts feeding real 656 // Start recording and verify that the native audio layer starts feeding real
859 // audio samples via the RecordedDataIsAvailable callback. 657 // audio samples via the RecordedDataIsAvailable callback.
860 TEST_F(AudioDeviceTest, StartRecordingVerifyCallbacks) { 658 TEST_F(AudioDeviceTest, StartRecordingVerifyCallbacks) {
861 MockAudioTransport mock(kRecording); 659 MockAudioTransport mock(kRecording);
862 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 660 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
863 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), 661 EXPECT_CALL(mock,
864 record_frames_per_10ms_buffer(), 662 RecordedDataIsAvailable(
865 kBytesPerSample, 663 NotNull(), record_frames_per_10ms_buffer(), kBytesPerSample,
866 record_channels(), 664 record_channels(), record_sample_rate(),
867 record_sample_rate(), 665 _, // TODO(henrika): fix delay
868 total_delay_ms(), 666 0, 0, false, _)).Times(AtLeast(kNumCallbacks));
869 0,
870 0,
871 false,
872 _))
873 .Times(AtLeast(kNumCallbacks));
874 667
875 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 668 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
876 StartRecording(); 669 StartRecording();
877 test_is_done_->Wait(kTestTimeOutInMilliseconds); 670 test_is_done_->Wait(kTestTimeOutInMilliseconds);
878 StopRecording(); 671 StopRecording();
879 } 672 }
880 673
881
882 // Start playout and recording (full-duplex audio) and verify that audio is 674 // Start playout and recording (full-duplex audio) and verify that audio is
883 // active in both directions. 675 // active in both directions.
884 TEST_F(AudioDeviceTest, StartPlayoutAndRecordingVerifyCallbacks) { 676 TEST_F(AudioDeviceTest, StartPlayoutAndRecordingVerifyCallbacks) {
885 MockAudioTransport mock(kPlayout | kRecording); 677 MockAudioTransport mock(kPlayout | kRecording);
886 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 678 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
887 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(), 679 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(),
888 kBytesPerSample, 680 kBytesPerSample, playout_channels(),
889 playout_channels(), 681 playout_sample_rate(), NotNull(), _, _, _))
890 playout_sample_rate(),
891 NotNull(),
892 _, _, _))
893 .Times(AtLeast(kNumCallbacks)); 682 .Times(AtLeast(kNumCallbacks));
894 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), 683 EXPECT_CALL(mock,
895 record_frames_per_10ms_buffer(), 684 RecordedDataIsAvailable(
896 kBytesPerSample, 685 NotNull(), record_frames_per_10ms_buffer(), kBytesPerSample,
897 record_channels(), 686 record_channels(), record_sample_rate(),
898 record_sample_rate(), 687 _, // TODO(henrika): fix delay
899 total_delay_ms(), 688 0, 0, false, _)).Times(AtLeast(kNumCallbacks));
900 0,
901 0,
902 false,
903 _))
904 .Times(AtLeast(kNumCallbacks));
905 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 689 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
906 StartPlayout(); 690 StartPlayout();
907 StartRecording(); 691 StartRecording();
908 test_is_done_->Wait(kTestTimeOutInMilliseconds); 692 test_is_done_->Wait(kTestTimeOutInMilliseconds);
909 StopRecording(); 693 StopRecording();
910 StopPlayout(); 694 StopPlayout();
911 } 695 }
912 696
913 // Start playout and read audio from an external PCM file when the audio layer 697 // Start playout and read audio from an external PCM file when the audio layer
914 // asks for data to play out. Real audio is played out in this test but it does 698 // asks for data to play out. Real audio is played out in this test but it does
915 // not contain any explicit verification that the audio quality is perfect. 699 // not contain any explicit verification that the audio quality is perfect.
916 TEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) { 700 TEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) {
917 // TODO(henrika): extend test when mono output is supported. 701 // TODO(henrika): extend test when mono output is supported.
918 EXPECT_EQ(1, playout_channels()); 702 EXPECT_EQ(1, playout_channels());
919 NiceMock<MockAudioTransport> mock(kPlayout); 703 NiceMock<MockAudioTransport> mock(kPlayout);
920 const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond; 704 const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond;
921 std::string file_name = GetFileName(playout_sample_rate()); 705 std::string file_name = GetFileName(playout_sample_rate());
922 rtc::scoped_ptr<FileAudioStream> file_audio_stream( 706 rtc::scoped_ptr<FileAudioStream> file_audio_stream(
923 new FileAudioStream(num_callbacks, file_name, playout_sample_rate())); 707 new FileAudioStream(num_callbacks, file_name, playout_sample_rate()));
924 mock.HandleCallbacks(test_is_done_.get(), 708 mock.HandleCallbacks(test_is_done_.get(), file_audio_stream.get(),
925 file_audio_stream.get(),
926 num_callbacks); 709 num_callbacks);
927 // SetMaxPlayoutVolume(); 710 // SetMaxPlayoutVolume();
928 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 711 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
929 StartPlayout(); 712 StartPlayout();
930 test_is_done_->Wait(kTestTimeOutInMilliseconds); 713 test_is_done_->Wait(kTestTimeOutInMilliseconds);
931 StopPlayout(); 714 StopPlayout();
932 } 715 }
933 716
717 TEST_F(AudioDeviceTest, Devices) {
718 // Device enumeration is not supported. Verify fixed values only.
719 EXPECT_EQ(1, audio_device()->PlayoutDevices());
720 EXPECT_EQ(1, audio_device()->RecordingDevices());
721 }
722
934 // Start playout and recording and store recorded data in an intermediate FIFO 723 // Start playout and recording and store recorded data in an intermediate FIFO
935 // buffer from which the playout side then reads its samples in the same order 724 // buffer from which the playout side then reads its samples in the same order
936 // as they were stored. Under ideal circumstances, a callback sequence would 725 // as they were stored. Under ideal circumstances, a callback sequence would
937 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-' 726 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-'
938 // means 'packet played'. Under such conditions, the FIFO would only contain 727 // means 'packet played'. Under such conditions, the FIFO would only contain
939 // one packet on average. However, under more realistic conditions, the size 728 // one packet on average. However, under more realistic conditions, the size
940 // of the FIFO will vary more due to an unbalance between the two sides. 729 // of the FIFO will vary more due to an unbalance between the two sides.
941 // This test tries to verify that the device maintains a balanced callback- 730 // This test tries to verify that the device maintains a balanced callback-
942 // sequence by running in loopback for ten seconds while measuring the size 731 // sequence by running in loopback for ten seconds while measuring the size
943 // (max and average) of the FIFO. The size of the FIFO is increased by the 732 // (max and average) of the FIFO. The size of the FIFO is increased by the
944 // recording side and decreased by the playout side. 733 // recording side and decreased by the playout side.
945 // TODO(henrika): tune the final test parameters after running tests on several 734 // TODO(henrika): tune the final test parameters after running tests on several
946 // different devices. 735 // different devices.
947 TEST_F(AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) { 736 TEST_F(AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) {
948 EXPECT_EQ(record_channels(), playout_channels()); 737 EXPECT_EQ(record_channels(), playout_channels());
949 EXPECT_EQ(record_sample_rate(), playout_sample_rate()); 738 EXPECT_EQ(record_sample_rate(), playout_sample_rate());
950 NiceMock<MockAudioTransport> mock(kPlayout | kRecording); 739 NiceMock<MockAudioTransport> mock(kPlayout | kRecording);
951 rtc::scoped_ptr<FifoAudioStream> fifo_audio_stream( 740 rtc::scoped_ptr<FifoAudioStream> fifo_audio_stream(
952 new FifoAudioStream(playout_frames_per_10ms_buffer())); 741 new FifoAudioStream(playout_frames_per_10ms_buffer()));
953 mock.HandleCallbacks(test_is_done_.get(), 742 mock.HandleCallbacks(test_is_done_.get(), fifo_audio_stream.get(),
954 fifo_audio_stream.get(),
955 kFullDuplexTimeInSec * kNumCallbacksPerSecond); 743 kFullDuplexTimeInSec * kNumCallbacksPerSecond);
956 SetMaxPlayoutVolume(); 744 // SetMaxPlayoutVolume();
957 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 745 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
958 StartRecording(); 746 StartRecording();
959 StartPlayout(); 747 StartPlayout();
960 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, 748 test_is_done_->Wait(
961 1000 * kFullDuplexTimeInSec)); 749 std::max(kTestTimeOutInMilliseconds, 1000 * kFullDuplexTimeInSec));
962 StopPlayout(); 750 StopPlayout();
963 StopRecording(); 751 StopRecording();
964 EXPECT_LE(fifo_audio_stream->average_size(), 10); 752 EXPECT_LE(fifo_audio_stream->average_size(), 10);
965 EXPECT_LE(fifo_audio_stream->largest_size(), 20); 753 EXPECT_LE(fifo_audio_stream->largest_size(), 20);
966 } 754 }
967 755
968 // Measures loopback latency and reports the min, max and average values for 756 // Measures loopback latency and reports the min, max and average values for
969 // a full duplex audio session. 757 // a full duplex audio session.
970 // The latency is measured like so: 758 // The latency is measured like so:
971 // - Insert impulses periodically on the output side. 759 // - Insert impulses periodically on the output side.
972 // - Detect the impulses on the input side. 760 // - Detect the impulses on the input side.
973 // - Measure the time difference between the transmit time and receive time. 761 // - Measure the time difference between the transmit time and receive time.
974 // - Store time differences in a vector and calculate min, max and average. 762 // - Store time differences in a vector and calculate min, max and average.
975 // This test requires a special hardware called Audio Loopback Dongle. 763 // This test requires a special hardware called Audio Loopback Dongle.
976 // See http://source.android.com/devices/audio/loopback.html for details. 764 // See http://source.android.com/devices/audio/loopback.html for details.
977 TEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) { 765 TEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) {
978 EXPECT_EQ(record_channels(), playout_channels()); 766 EXPECT_EQ(record_channels(), playout_channels());
979 EXPECT_EQ(record_sample_rate(), playout_sample_rate()); 767 EXPECT_EQ(record_sample_rate(), playout_sample_rate());
980 NiceMock<MockAudioTransport> mock(kPlayout | kRecording); 768 NiceMock<MockAudioTransport> mock(kPlayout | kRecording);
981 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream( 769 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream(
982 new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer())); 770 new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer()));
983 mock.HandleCallbacks(test_is_done_.get(), 771 mock.HandleCallbacks(test_is_done_.get(), latency_audio_stream.get(),
984 latency_audio_stream.get(),
985 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond); 772 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond);
986 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 773 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
987 SetMaxPlayoutVolume(); 774 // SetMaxPlayoutVolume();
988 DisableBuiltInAECIfAvailable(); 775 // DisableBuiltInAECIfAvailable();
989 StartRecording(); 776 StartRecording();
990 StartPlayout(); 777 StartPlayout();
991 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, 778 test_is_done_->Wait(
992 1000 * kMeasureLatencyTimeInSec)); 779 std::max(kTestTimeOutInMilliseconds, 1000 * kMeasureLatencyTimeInSec));
993 StopPlayout(); 780 StopPlayout();
994 StopRecording(); 781 StopRecording();
995 // Verify that the correct number of transmitted impulses are detected. 782 // Verify that the correct number of transmitted impulses are detected.
996 EXPECT_EQ(latency_audio_stream->num_latency_values(), 783 EXPECT_EQ(latency_audio_stream->num_latency_values(),
997 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1); 784 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1);
998 latency_audio_stream->PrintResults(); 785 latency_audio_stream->PrintResults();
999 } 786 }
1000 787
1001 } // namespace webrtc 788 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_device/ios/audio_device_not_implemented_ios.mm ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698