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