1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <algorithm>
12 #include <limits>
13 #include <list>
14 #include <memory>
15 #include <numeric>
16 #include <string>
17 #include <vector>
18
19 #include "webrtc/base/arraysize.h"
20 #include "webrtc/base/criticalsection.h"
21 #include "webrtc/base/format_macros.h"
22 #include "webrtc/base/scoped_ref_ptr.h"
23 #include "webrtc/base/timeutils.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"
29 #include "webrtc/modules/audio_device/include/audio_device.h"
30 #include "webrtc/modules/audio_device/include/mock_audio_transport.h"
31 #include "webrtc/system_wrappers/include/event_wrapper.h"
32 #include "webrtc/system_wrappers/include/sleep.h"
33 #include "webrtc/test/gmock.h"
34 #include "webrtc/test/gtest.h"
35 #include "webrtc/test/testsupport/fileutils.h"
36
37 using std::cout;
38 using std::endl;
39 using ::testing::_;
40 using ::testing::AtLeast;
41 using ::testing::Gt;
42 using ::testing::Invoke;
43 using ::testing::NiceMock;
44 using ::testing::NotNull;
45 using ::testing::Return;
46
47 // #define ENABLE_DEBUG_PRINTF
48 #ifdef ENABLE_DEBUG_PRINTF
49 #define PRINTD(...) fprintf(stderr, __VA_ARGS__);
50 #else
51 #define PRINTD(...) ((void)0)
52 #endif
53 #define PRINT(...) fprintf(stderr, __VA_ARGS__);
54
55 namespace webrtc {
56
57 // Number of callbacks (input or output) the tests waits for before we set
58 // an event indicating that the test was OK.
59 static const size_t kNumCallbacks = 10;
60 // Max amount of time we wait for an event to be set while counting callbacks.
61 static const int kTestTimeOutInMilliseconds = 10 * 1000;
62 // Average number of audio callbacks per second assuming 10ms packet size.
63 static const size_t kNumCallbacksPerSecond = 100;
64 // Play out a test file during this time (unit is in seconds).
65 static const int kFilePlayTimeInSec = 5;
66 static const size_t kBitsPerSample = 16;
67 static const size_t kBytesPerSample = kBitsPerSample / 8;
68 // Run the full-duplex test during this time (unit is in seconds).
69 // Note that first |kNumIgnoreFirstCallbacks| are ignored.
70 static const int kFullDuplexTimeInSec = 5;
71 // Wait for the callback sequence to stabilize by ignoring this amount of the
72 // initial callbacks (avoids initial FIFO access).
73 // Only used in the RunPlayoutAndRecordingInFullDuplex test.
74 static const size_t kNumIgnoreFirstCallbacks = 50;
75 // Sets the number of impulses per second in the latency test.
76 static const int kImpulseFrequencyInHz = 1;
77 // Length of round-trip latency measurements. Number of transmitted impulses
78 // is kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1.
79 static const int kMeasureLatencyTimeInSec = 11;
80 // Utilized in round-trip latency measurements to avoid capturing noise samples.
81 static const int kImpulseThreshold = 1000;
82 static const char kTag[] = "[..........] ";
83
84 enum TransportType {
85 kPlayout = 0x1,
86 kRecording = 0x2,
87 };
88
89 // Interface for processing the audio stream. Real implementations can e.g.
90 // run audio in loopback, read audio from a file or perform latency
91 // measurements.
92 class AudioStreamInterface {
93 public:
94 virtual void Write(const void* source, size_t num_frames) = 0;
95 virtual void Read(void* destination, size_t num_frames) = 0;
96 protected:
~AudioStreamInterface()97 virtual ~AudioStreamInterface() {}
98 };
99
100 // Reads audio samples from a PCM file where the file is stored in memory at
101 // construction.
102 class FileAudioStream : public AudioStreamInterface {
103 public:
FileAudioStream(size_t num_callbacks,const std::string & file_name,int sample_rate)104 FileAudioStream(
105 size_t num_callbacks, const std::string& file_name, int sample_rate)
106 : file_size_in_bytes_(0),
107 sample_rate_(sample_rate),
108 file_pos_(0) {
109 file_size_in_bytes_ = test::GetFileSize(file_name);
110 sample_rate_ = sample_rate;
111 EXPECT_GE(file_size_in_callbacks(), num_callbacks)
112 << "Size of test file is not large enough to last during the test.";
113 const size_t num_16bit_samples =
114 test::GetFileSize(file_name) / kBytesPerSample;
115 file_.reset(new int16_t[num_16bit_samples]);
116 FILE* audio_file = fopen(file_name.c_str(), "rb");
117 EXPECT_NE(audio_file, nullptr);
118 size_t num_samples_read = fread(
119 file_.get(), sizeof(int16_t), num_16bit_samples, audio_file);
120 EXPECT_EQ(num_samples_read, num_16bit_samples);
121 fclose(audio_file);
122 }
123
124 // AudioStreamInterface::Write() is not implemented.
Write(const void * source,size_t num_frames)125 void Write(const void* source, size_t num_frames) override {}
126
127 // Read samples from file stored in memory (at construction) and copy
128 // |num_frames| (<=> 10ms) to the |destination| byte buffer.
Read(void * destination,size_t num_frames)129 void Read(void* destination, size_t num_frames) override {
130 memcpy(destination,
131 static_cast<int16_t*> (&file_[file_pos_]),
132 num_frames * sizeof(int16_t));
133 file_pos_ += num_frames;
134 }
135
file_size_in_seconds() const136 int file_size_in_seconds() const {
137 return static_cast<int>(
138 file_size_in_bytes_ / (kBytesPerSample * sample_rate_));
139 }
file_size_in_callbacks() const140 size_t file_size_in_callbacks() const {
141 return file_size_in_seconds() * kNumCallbacksPerSecond;
142 }
143
144 private:
145 size_t file_size_in_bytes_;
146 int sample_rate_;
147 std::unique_ptr<int16_t[]> file_;
148 size_t file_pos_;
149 };
150
151 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio
152 // buffers of fixed size and allows Write and Read operations. The idea is to
153 // store recorded audio buffers (using Write) and then read (using Read) these
154 // stored buffers with as short delay as possible when the audio layer needs
155 // data to play out. The number of buffers in the FIFO will stabilize under
156 // normal conditions since there will be a balance between Write and Read calls.
157 // The container is a std::list container and access is protected with a lock
158 // since both sides (playout and recording) are driven by its own thread.
159 class FifoAudioStream : public AudioStreamInterface {
160 public:
FifoAudioStream(size_t frames_per_buffer)161 explicit FifoAudioStream(size_t frames_per_buffer)
162 : frames_per_buffer_(frames_per_buffer),
163 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
164 fifo_(new AudioBufferList),
165 largest_size_(0),
166 total_written_elements_(0),
167 write_count_(0) {
168 EXPECT_NE(fifo_.get(), nullptr);
169 }
170
~FifoAudioStream()171 ~FifoAudioStream() {
172 Flush();
173 }
174
175 // Allocate new memory, copy |num_frames| samples from |source| into memory
176 // and add pointer to the memory location to end of the list.
177 // Increases the size of the FIFO by one element.
Write(const void * source,size_t num_frames)178 void Write(const void* source, size_t num_frames) override {
179 ASSERT_EQ(num_frames, frames_per_buffer_);
180 PRINTD("+");
181 if (write_count_++ < kNumIgnoreFirstCallbacks) {
182 return;
183 }
184 int16_t* memory = new int16_t[frames_per_buffer_];
185 memcpy(static_cast<int16_t*> (&memory[0]),
186 source,
187 bytes_per_buffer_);
188 rtc::CritScope lock(&lock_);
189 fifo_->push_back(memory);
190 const size_t size = fifo_->size();
191 if (size > largest_size_) {
192 largest_size_ = size;
193 PRINTD("(%" PRIuS ")", largest_size_);
194 }
195 total_written_elements_ += size;
196 }
197
198 // Read pointer to data buffer from front of list, copy |num_frames| of stored
199 // data into |destination| and delete the utilized memory allocation.
200 // Decreases the size of the FIFO by one element.
Read(void * destination,size_t num_frames)201 void Read(void* destination, size_t num_frames) override {
202 ASSERT_EQ(num_frames, frames_per_buffer_);
203 PRINTD("-");
204 rtc::CritScope lock(&lock_);
205 if (fifo_->empty()) {
206 memset(destination, 0, bytes_per_buffer_);
207 } else {
208 int16_t* memory = fifo_->front();
209 fifo_->pop_front();
210 memcpy(destination,
211 static_cast<int16_t*> (&memory[0]),
212 bytes_per_buffer_);
213 delete memory;
214 }
215 }
216
size() const217 size_t size() const {
218 return fifo_->size();
219 }
220
largest_size() const221 size_t largest_size() const {
222 return largest_size_;
223 }
224
average_size() const225 size_t average_size() const {
226 return (total_written_elements_ == 0) ? 0.0 : 0.5 + static_cast<float> (
227 total_written_elements_) / (write_count_ - kNumIgnoreFirstCallbacks);
228 }
229
230 private:
Flush()231 void Flush() {
232 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) {
233 delete *it;
234 }
235 fifo_->clear();
236 }
237
238 using AudioBufferList = std::list<int16_t*>;
239 rtc::CriticalSection lock_;
240 const size_t frames_per_buffer_;
241 const size_t bytes_per_buffer_;
242 std::unique_ptr<AudioBufferList> fifo_;
243 size_t largest_size_;
244 size_t total_written_elements_;
245 size_t write_count_;
246 };
247
248 // Inserts periodic impulses and measures the latency between the time of
249 // transmission and time of receiving the same impulse.
250 // Usage requires a special hardware called Audio Loopback Dongle.
251 // See http://source.android.com/devices/audio/loopback.html for details.
252 class LatencyMeasuringAudioStream : public AudioStreamInterface {
253 public:
LatencyMeasuringAudioStream(size_t frames_per_buffer)254 explicit LatencyMeasuringAudioStream(size_t frames_per_buffer)
255 : frames_per_buffer_(frames_per_buffer),
256 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
257 play_count_(0),
258 rec_count_(0),
259 pulse_time_(0) {
260 }
261
262 // Insert periodic impulses in first two samples of |destination|.
Read(void * destination,size_t num_frames)263 void Read(void* destination, size_t num_frames) override {
264 ASSERT_EQ(num_frames, frames_per_buffer_);
265 if (play_count_ == 0) {
266 PRINT("[");
267 }
268 play_count_++;
269 memset(destination, 0, bytes_per_buffer_);
270 if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) {
271 if (pulse_time_ == 0) {
272 pulse_time_ = rtc::TimeMillis();
273 }
274 PRINT(".");
275 const int16_t impulse = std::numeric_limits<int16_t>::max();
276 int16_t* ptr16 = static_cast<int16_t*> (destination);
277 for (size_t i = 0; i < 2; ++i) {
278 ptr16[i] = impulse;
279 }
280 }
281 }
282
283 // Detect received impulses in |source|, derive time between transmission and
284 // detection and add the calculated delay to list of latencies.
Write(const void * source,size_t num_frames)285 void Write(const void* source, size_t num_frames) override {
286 ASSERT_EQ(num_frames, frames_per_buffer_);
287 rec_count_++;
288 if (pulse_time_ == 0) {
289 // Avoid detection of new impulse response until a new impulse has
290 // been transmitted (sets |pulse_time_| to value larger than zero).
291 return;
292 }
293 const int16_t* ptr16 = static_cast<const int16_t*> (source);
294 std::vector<int16_t> vec(ptr16, ptr16 + num_frames);
295 // Find max value in the audio buffer.
296 int max = *std::max_element(vec.begin(), vec.end());
297 // Find index (element position in vector) of the max element.
298 int index_of_max = std::distance(vec.begin(),
299 std::find(vec.begin(), vec.end(),
300 max));
301 if (max > kImpulseThreshold) {
302 PRINTD("(%d,%d)", max, index_of_max);
303 int64_t now_time = rtc::TimeMillis();
304 int extra_delay = IndexToMilliseconds(static_cast<double> (index_of_max));
305 PRINTD("[%d]", static_cast<int> (now_time - pulse_time_));
306 PRINTD("[%d]", extra_delay);
307 // Total latency is the difference between transmit time and detection
308 // tome plus the extra delay within the buffer in which we detected the
309 // received impulse. It is transmitted at sample 0 but can be received
310 // at sample N where N > 0. The term |extra_delay| accounts for N and it
311 // is a value between 0 and 10ms.
312 latencies_.push_back(now_time - pulse_time_ + extra_delay);
313 pulse_time_ = 0;
314 } else {
315 PRINTD("-");
316 }
317 }
318
num_latency_values() const319 size_t num_latency_values() const {
320 return latencies_.size();
321 }
322
min_latency() const323 int min_latency() const {
324 if (latencies_.empty())
325 return 0;
326 return *std::min_element(latencies_.begin(), latencies_.end());
327 }
328
max_latency() const329 int max_latency() const {
330 if (latencies_.empty())
331 return 0;
332 return *std::max_element(latencies_.begin(), latencies_.end());
333 }
334
average_latency() const335 int average_latency() const {
336 if (latencies_.empty())
337 return 0;
338 return 0.5 + static_cast<double> (
339 std::accumulate(latencies_.begin(), latencies_.end(), 0)) /
340 latencies_.size();
341 }
342
PrintResults() const343 void PrintResults() const {
344 PRINT("] ");
345 for (auto it = latencies_.begin(); it != latencies_.end(); ++it) {
346 PRINT("%d ", *it);
347 }
348 PRINT("\n");
349 PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag,
350 min_latency(), max_latency(), average_latency());
351 }
352
IndexToMilliseconds(double index) const353 int IndexToMilliseconds(double index) const {
354 return static_cast<int>(10.0 * (index / frames_per_buffer_) + 0.5);
355 }
356
357 private:
358 const size_t frames_per_buffer_;
359 const size_t bytes_per_buffer_;
360 size_t play_count_;
361 size_t rec_count_;
362 int64_t pulse_time_;
363 std::vector<int> latencies_;
364 };
365
366 // Mocks the AudioTransport object and proxies actions for the two callbacks
367 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations
368 // of AudioStreamInterface.
369 class MockAudioTransportAndroid : public test::MockAudioTransport {
370 public:
MockAudioTransportAndroid(int type)371 explicit MockAudioTransportAndroid(int type)
372 : num_callbacks_(0),
373 type_(type),
374 play_count_(0),
375 rec_count_(0),
376 audio_stream_(nullptr) {}
377
~MockAudioTransportAndroid()378 virtual ~MockAudioTransportAndroid() {}
379
380 // Set default actions of the mock object. We are delegating to fake
381 // implementations (of AudioStreamInterface) here.
HandleCallbacks(EventWrapper * test_is_done,AudioStreamInterface * audio_stream,int num_callbacks)382 void HandleCallbacks(EventWrapper* test_is_done,
383 AudioStreamInterface* audio_stream,
384 int num_callbacks) {
385 test_is_done_ = test_is_done;
386 audio_stream_ = audio_stream;
387 num_callbacks_ = num_callbacks;
388 if (play_mode()) {
389 ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _))
390 .WillByDefault(
391 Invoke(this, &MockAudioTransportAndroid::RealNeedMorePlayData));
392 }
393 if (rec_mode()) {
394 ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _))
395 .WillByDefault(Invoke(
396 this, &MockAudioTransportAndroid::RealRecordedDataIsAvailable));
397 }
398 }
399
RealRecordedDataIsAvailable(const void * audioSamples,const size_t nSamples,const size_t nBytesPerSample,const size_t nChannels,const uint32_t samplesPerSec,const uint32_t totalDelayMS,const int32_t clockDrift,const uint32_t currentMicLevel,const bool keyPressed,uint32_t & newMicLevel)400 int32_t RealRecordedDataIsAvailable(const void* audioSamples,
401 const size_t nSamples,
402 const size_t nBytesPerSample,
403 const size_t nChannels,
404 const uint32_t samplesPerSec,
405 const uint32_t totalDelayMS,
406 const int32_t clockDrift,
407 const uint32_t currentMicLevel,
408 const bool keyPressed,
409 uint32_t& newMicLevel) {
410 EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks.";
411 rec_count_++;
412 // Process the recorded audio stream if an AudioStreamInterface
413 // implementation exists.
414 if (audio_stream_) {
415 audio_stream_->Write(audioSamples, nSamples);
416 }
417 if (ReceivedEnoughCallbacks()) {
418 test_is_done_->Set();
419 }
420 return 0;
421 }
422
RealNeedMorePlayData(const size_t nSamples,const size_t nBytesPerSample,const size_t nChannels,const uint32_t samplesPerSec,void * audioSamples,size_t & nSamplesOut,int64_t * elapsed_time_ms,int64_t * ntp_time_ms)423 int32_t RealNeedMorePlayData(const size_t nSamples,
424 const size_t nBytesPerSample,
425 const size_t nChannels,
426 const uint32_t samplesPerSec,
427 void* audioSamples,
428 size_t& nSamplesOut,
429 int64_t* elapsed_time_ms,
430 int64_t* ntp_time_ms) {
431 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks.";
432 play_count_++;
433 nSamplesOut = nSamples;
434 // Read (possibly processed) audio stream samples to be played out if an
435 // AudioStreamInterface implementation exists.
436 if (audio_stream_) {
437 audio_stream_->Read(audioSamples, nSamples);
438 }
439 if (ReceivedEnoughCallbacks()) {
440 test_is_done_->Set();
441 }
442 return 0;
443 }
444
ReceivedEnoughCallbacks()445 bool ReceivedEnoughCallbacks() {
446 bool recording_done = false;
447 if (rec_mode())
448 recording_done = rec_count_ >= num_callbacks_;
449 else
450 recording_done = true;
451
452 bool playout_done = false;
453 if (play_mode())
454 playout_done = play_count_ >= num_callbacks_;
455 else
456 playout_done = true;
457
458 return recording_done && playout_done;
459 }
460
play_mode() const461 bool play_mode() const { return type_ & kPlayout; }
rec_mode() const462 bool rec_mode() const { return type_ & kRecording; }
463
464 private:
465 EventWrapper* test_is_done_;
466 size_t num_callbacks_;
467 int type_;
468 size_t play_count_;
469 size_t rec_count_;
470 AudioStreamInterface* audio_stream_;
471 std::unique_ptr<LatencyMeasuringAudioStream> latency_audio_stream_;
472 };
473
474 // AudioDeviceTest test fixture.
475 class AudioDeviceTest : public ::testing::Test {
476 protected:
AudioDeviceTest()477 AudioDeviceTest()
478 : test_is_done_(EventWrapper::Create()) {
479 // One-time initialization of JVM and application context. Ensures that we
480 // can do calls between C++ and Java. Initializes both Java and OpenSL ES
481 // implementations.
482 webrtc::audiodevicemodule::EnsureInitialized();
483 // Creates an audio device using a default audio layer.
484 audio_device_ = CreateAudioDevice(AudioDeviceModule::kPlatformDefaultAudio);
485 EXPECT_NE(audio_device_.get(), nullptr);
486 EXPECT_EQ(0, audio_device_->Init());
487 playout_parameters_ = audio_manager()->GetPlayoutAudioParameters();
488 record_parameters_ = audio_manager()->GetRecordAudioParameters();
489 build_info_.reset(new BuildInfo());
490 }
~AudioDeviceTest()491 virtual ~AudioDeviceTest() {
492 EXPECT_EQ(0, audio_device_->Terminate());
493 }
494
playout_sample_rate() const495 int playout_sample_rate() const {
496 return playout_parameters_.sample_rate();
497 }
record_sample_rate() const498 int record_sample_rate() const {
499 return record_parameters_.sample_rate();
500 }
playout_channels() const501 size_t playout_channels() const {
502 return playout_parameters_.channels();
503 }
record_channels() const504 size_t record_channels() const {
505 return record_parameters_.channels();
506 }
playout_frames_per_10ms_buffer() const507 size_t playout_frames_per_10ms_buffer() const {
508 return playout_parameters_.frames_per_10ms_buffer();
509 }
record_frames_per_10ms_buffer() const510 size_t record_frames_per_10ms_buffer() const {
511 return record_parameters_.frames_per_10ms_buffer();
512 }
513
total_delay_ms() const514 int total_delay_ms() const {
515 return audio_manager()->GetDelayEstimateInMilliseconds();
516 }
517
audio_device() const518 rtc::scoped_refptr<AudioDeviceModule> audio_device() const {
519 return audio_device_;
520 }
521
audio_device_impl() const522 AudioDeviceModuleImpl* audio_device_impl() const {
523 return static_cast<AudioDeviceModuleImpl*>(audio_device_.get());
524 }
525
audio_manager() const526 AudioManager* audio_manager() const {
527 return audio_device_impl()->GetAndroidAudioManagerForTest();
528 }
529
GetAudioManager(AudioDeviceModule * adm) const530 AudioManager* GetAudioManager(AudioDeviceModule* adm) const {
531 return static_cast<AudioDeviceModuleImpl*>(adm)->
532 GetAndroidAudioManagerForTest();
533 }
534
audio_device_buffer() const535 AudioDeviceBuffer* audio_device_buffer() const {
536 return audio_device_impl()->GetAudioDeviceBuffer();
537 }
538
CreateAudioDevice(AudioDeviceModule::AudioLayer audio_layer)539 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDevice(
540 AudioDeviceModule::AudioLayer audio_layer) {
541 rtc::scoped_refptr<AudioDeviceModule> module(
542 AudioDeviceModule::Create(0, audio_layer));
543 return module;
544 }
545
546 // Returns file name relative to the resource root given a sample rate.
GetFileName(int sample_rate)547 std::string GetFileName(int sample_rate) {
548 EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100);
549 char fname[64];
550 snprintf(fname,
551 sizeof(fname),
552 "audio_device/audio_short%d",
553 sample_rate / 1000);
554 std::string file_name(webrtc::test::ResourcePath(fname, "pcm"));
555 EXPECT_TRUE(test::FileExists(file_name));
556 #ifdef ENABLE_PRINTF
557 PRINT("file name: %s\n", file_name.c_str());
558 const size_t bytes = test::GetFileSize(file_name);
559 PRINT("file size: %" PRIuS " [bytes]\n", bytes);
560 PRINT("file size: %" PRIuS " [samples]\n", bytes / kBytesPerSample);
561 const int seconds =
562 static_cast<int>(bytes / (sample_rate * kBytesPerSample));
563 PRINT("file size: %d [secs]\n", seconds);
564 PRINT("file size: %" PRIuS " [callbacks]\n",
565 seconds * kNumCallbacksPerSecond);
566 #endif
567 return file_name;
568 }
569
GetActiveAudioLayer() const570 AudioDeviceModule::AudioLayer GetActiveAudioLayer() const {
571 AudioDeviceModule::AudioLayer audio_layer;
572 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer));
573 return audio_layer;
574 }
575
TestDelayOnAudioLayer(const AudioDeviceModule::AudioLayer & layer_to_test)576 int TestDelayOnAudioLayer(
577 const AudioDeviceModule::AudioLayer& layer_to_test) {
578 rtc::scoped_refptr<AudioDeviceModule> audio_device;
579 audio_device = CreateAudioDevice(layer_to_test);
580 EXPECT_NE(audio_device.get(), nullptr);
581 AudioManager* audio_manager = GetAudioManager(audio_device.get());
582 EXPECT_NE(audio_manager, nullptr);
583 return audio_manager->GetDelayEstimateInMilliseconds();
584 }
585
TestActiveAudioLayer(const AudioDeviceModule::AudioLayer & layer_to_test)586 AudioDeviceModule::AudioLayer TestActiveAudioLayer(
587 const AudioDeviceModule::AudioLayer& layer_to_test) {
588 rtc::scoped_refptr<AudioDeviceModule> audio_device;
589 audio_device = CreateAudioDevice(layer_to_test);
590 EXPECT_NE(audio_device.get(), nullptr);
591 AudioDeviceModule::AudioLayer active;
592 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&active));
593 return active;
594 }
595
DisableTestForThisDevice(const std::string & model)596 bool DisableTestForThisDevice(const std::string& model) {
597 return (build_info_->GetDeviceModel() == model);
598 }
599
600 // Volume control is currently only supported for the Java output audio layer.
601 // For OpenSL ES, the internal stream volume is always on max level and there
602 // is no need for this test to set it to max.
AudioLayerSupportsVolumeControl() const603 bool AudioLayerSupportsVolumeControl() const {
604 return GetActiveAudioLayer() == AudioDeviceModule::kAndroidJavaAudio;
605 }
606
SetMaxPlayoutVolume()607 void SetMaxPlayoutVolume() {
608 if (!AudioLayerSupportsVolumeControl())
609 return;
610 uint32_t max_volume;
611 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume));
612 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume));
613 }
614
DisableBuiltInAECIfAvailable()615 void DisableBuiltInAECIfAvailable() {
616 if (audio_device()->BuiltInAECIsAvailable()) {
617 EXPECT_EQ(0, audio_device()->EnableBuiltInAEC(false));
618 }
619 }
620
StartPlayout()621 void StartPlayout() {
622 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
623 EXPECT_FALSE(audio_device()->Playing());
624 EXPECT_EQ(0, audio_device()->InitPlayout());
625 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
626 EXPECT_EQ(0, audio_device()->StartPlayout());
627 EXPECT_TRUE(audio_device()->Playing());
628 }
629
StopPlayout()630 void StopPlayout() {
631 EXPECT_EQ(0, audio_device()->StopPlayout());
632 EXPECT_FALSE(audio_device()->Playing());
633 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
634 }
635
StartRecording()636 void StartRecording() {
637 EXPECT_FALSE(audio_device()->RecordingIsInitialized());
638 EXPECT_FALSE(audio_device()->Recording());
639 EXPECT_EQ(0, audio_device()->InitRecording());
640 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
641 EXPECT_EQ(0, audio_device()->StartRecording());
642 EXPECT_TRUE(audio_device()->Recording());
643 }
644
StopRecording()645 void StopRecording() {
646 EXPECT_EQ(0, audio_device()->StopRecording());
647 EXPECT_FALSE(audio_device()->Recording());
648 }
649
GetMaxSpeakerVolume() const650 int GetMaxSpeakerVolume() const {
651 uint32_t max_volume(0);
652 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume));
653 return max_volume;
654 }
655
GetMinSpeakerVolume() const656 int GetMinSpeakerVolume() const {
657 uint32_t min_volume(0);
658 EXPECT_EQ(0, audio_device()->MinSpeakerVolume(&min_volume));
659 return min_volume;
660 }
661
GetSpeakerVolume() const662 int GetSpeakerVolume() const {
663 uint32_t volume(0);
664 EXPECT_EQ(0, audio_device()->SpeakerVolume(&volume));
665 return volume;
666 }
667
668 std::unique_ptr<EventWrapper> test_is_done_;
669 rtc::scoped_refptr<AudioDeviceModule> audio_device_;
670 AudioParameters playout_parameters_;
671 AudioParameters record_parameters_;
672 std::unique_ptr<BuildInfo> build_info_;
673 };
674
TEST_F(AudioDeviceTest,ConstructDestruct)675 TEST_F(AudioDeviceTest, ConstructDestruct) {
676 // Using the test fixture to create and destruct the audio device module.
677 }
678
679 // We always ask for a default audio layer when the ADM is constructed. But the
680 // ADM will then internally set the best suitable combination of audio layers,
681 // for input and output based on if low-latency output and/or input audio in
682 // combination with OpenSL ES is supported or not. This test ensures that the
683 // correct selection is done.
TEST_F(AudioDeviceTest,VerifyDefaultAudioLayer)684 TEST_F(AudioDeviceTest, VerifyDefaultAudioLayer) {
685 const AudioDeviceModule::AudioLayer audio_layer = GetActiveAudioLayer();
686 bool low_latency_output = audio_manager()->IsLowLatencyPlayoutSupported();
687 bool low_latency_input = audio_manager()->IsLowLatencyRecordSupported();
688 AudioDeviceModule::AudioLayer expected_audio_layer;
689 if (low_latency_output && low_latency_input) {
690 expected_audio_layer = AudioDeviceModule::kAndroidOpenSLESAudio;
691 } else if (low_latency_output && !low_latency_input) {
692 expected_audio_layer =
693 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio;
694 } else {
695 expected_audio_layer = AudioDeviceModule::kAndroidJavaAudio;
696 }
697 EXPECT_EQ(expected_audio_layer, audio_layer);
698 }
699
700 // Verify that it is possible to explicitly create the two types of supported
701 // ADMs. These two tests overrides the default selection of native audio layer
702 // by ignoring if the device supports low-latency output or not.
TEST_F(AudioDeviceTest,CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo)703 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo) {
704 AudioDeviceModule::AudioLayer expected_layer =
705 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio;
706 AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer(
707 expected_layer);
708 EXPECT_EQ(expected_layer, active_layer);
709 }
710
TEST_F(AudioDeviceTest,CorrectAudioLayerIsUsedForJavaInBothDirections)711 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForJavaInBothDirections) {
712 AudioDeviceModule::AudioLayer expected_layer =
713 AudioDeviceModule::kAndroidJavaAudio;
714 AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer(
715 expected_layer);
716 EXPECT_EQ(expected_layer, active_layer);
717 }
718
TEST_F(AudioDeviceTest,CorrectAudioLayerIsUsedForOpenSLInBothDirections)719 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForOpenSLInBothDirections) {
720 AudioDeviceModule::AudioLayer expected_layer =
721 AudioDeviceModule::kAndroidOpenSLESAudio;
722 AudioDeviceModule::AudioLayer active_layer =
723 TestActiveAudioLayer(expected_layer);
724 EXPECT_EQ(expected_layer, active_layer);
725 }
726
727 // The Android ADM supports two different delay reporting modes. One for the
728 // low-latency output path (in combination with OpenSL ES), and one for the
729 // high-latency output path (Java backends in both directions). These two tests
730 // verifies that the audio manager reports correct delay estimate given the
731 // selected audio layer. Note that, this delay estimate will only be utilized
732 // if the HW AEC is disabled.
TEST_F(AudioDeviceTest,UsesCorrectDelayEstimateForHighLatencyOutputPath)733 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForHighLatencyOutputPath) {
734 EXPECT_EQ(kHighLatencyModeDelayEstimateInMilliseconds,
735 TestDelayOnAudioLayer(AudioDeviceModule::kAndroidJavaAudio));
736 }
737
TEST_F(AudioDeviceTest,UsesCorrectDelayEstimateForLowLatencyOutputPath)738 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForLowLatencyOutputPath) {
739 EXPECT_EQ(kLowLatencyModeDelayEstimateInMilliseconds,
740 TestDelayOnAudioLayer(
741 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio));
742 }
743
744 // Ensure that the ADM internal audio device buffer is configured to use the
745 // correct set of parameters.
TEST_F(AudioDeviceTest,VerifyAudioDeviceBufferParameters)746 TEST_F(AudioDeviceTest, VerifyAudioDeviceBufferParameters) {
747 EXPECT_EQ(playout_parameters_.sample_rate(),
748 audio_device_buffer()->PlayoutSampleRate());
749 EXPECT_EQ(record_parameters_.sample_rate(),
750 audio_device_buffer()->RecordingSampleRate());
751 EXPECT_EQ(playout_parameters_.channels(),
752 audio_device_buffer()->PlayoutChannels());
753 EXPECT_EQ(record_parameters_.channels(),
754 audio_device_buffer()->RecordingChannels());
755 }
756
757
TEST_F(AudioDeviceTest,InitTerminate)758 TEST_F(AudioDeviceTest, InitTerminate) {
759 // Initialization is part of the test fixture.
760 EXPECT_TRUE(audio_device()->Initialized());
761 EXPECT_EQ(0, audio_device()->Terminate());
762 EXPECT_FALSE(audio_device()->Initialized());
763 }
764
TEST_F(AudioDeviceTest,Devices)765 TEST_F(AudioDeviceTest, Devices) {
766 // Device enumeration is not supported. Verify fixed values only.
767 EXPECT_EQ(1, audio_device()->PlayoutDevices());
768 EXPECT_EQ(1, audio_device()->RecordingDevices());
769 }
770
TEST_F(AudioDeviceTest,SpeakerVolumeShouldBeAvailable)771 TEST_F(AudioDeviceTest, SpeakerVolumeShouldBeAvailable) {
772 // The OpenSL ES output audio path does not support volume control.
773 if (!AudioLayerSupportsVolumeControl())
774 return;
775 bool available;
776 EXPECT_EQ(0, audio_device()->SpeakerVolumeIsAvailable(&available));
777 EXPECT_TRUE(available);
778 }
779
TEST_F(AudioDeviceTest,MaxSpeakerVolumeIsPositive)780 TEST_F(AudioDeviceTest, MaxSpeakerVolumeIsPositive) {
781 // The OpenSL ES output audio path does not support volume control.
782 if (!AudioLayerSupportsVolumeControl())
783 return;
784 StartPlayout();
785 EXPECT_GT(GetMaxSpeakerVolume(), 0);
786 StopPlayout();
787 }
788
TEST_F(AudioDeviceTest,MinSpeakerVolumeIsZero)789 TEST_F(AudioDeviceTest, MinSpeakerVolumeIsZero) {
790 // The OpenSL ES output audio path does not support volume control.
791 if (!AudioLayerSupportsVolumeControl())
792 return;
793 EXPECT_EQ(GetMinSpeakerVolume(), 0);
794 }
795
TEST_F(AudioDeviceTest,DefaultSpeakerVolumeIsWithinMinMax)796 TEST_F(AudioDeviceTest, DefaultSpeakerVolumeIsWithinMinMax) {
797 // The OpenSL ES output audio path does not support volume control.
798 if (!AudioLayerSupportsVolumeControl())
799 return;
800 const int default_volume = GetSpeakerVolume();
801 EXPECT_GE(default_volume, GetMinSpeakerVolume());
802 EXPECT_LE(default_volume, GetMaxSpeakerVolume());
803 }
804
TEST_F(AudioDeviceTest,SetSpeakerVolumeActuallySetsVolume)805 TEST_F(AudioDeviceTest, SetSpeakerVolumeActuallySetsVolume) {
806 // The OpenSL ES output audio path does not support volume control.
807 if (!AudioLayerSupportsVolumeControl())
808 return;
809 const int default_volume = GetSpeakerVolume();
810 const int max_volume = GetMaxSpeakerVolume();
811 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume));
812 int new_volume = GetSpeakerVolume();
813 EXPECT_EQ(new_volume, max_volume);
814 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(default_volume));
815 }
816
817 // Tests that playout can be initiated, started and stopped. No audio callback
818 // is registered in this test.
TEST_F(AudioDeviceTest,StartStopPlayout)819 TEST_F(AudioDeviceTest, StartStopPlayout) {
820 StartPlayout();
821 StopPlayout();
822 StartPlayout();
823 StopPlayout();
824 }
825
826 // Tests that recording can be initiated, started and stopped. No audio callback
827 // is registered in this test.
TEST_F(AudioDeviceTest,StartStopRecording)828 TEST_F(AudioDeviceTest, StartStopRecording) {
829 StartRecording();
830 StopRecording();
831 StartRecording();
832 StopRecording();
833 }
834
835 // Verify that calling StopPlayout() will leave us in an uninitialized state
836 // which will require a new call to InitPlayout(). This test does not call
837 // StartPlayout() while being uninitialized since doing so will hit a
838 // RTC_DCHECK and death tests are not supported on Android.
TEST_F(AudioDeviceTest,StopPlayoutRequiresInitToRestart)839 TEST_F(AudioDeviceTest, StopPlayoutRequiresInitToRestart) {
840 EXPECT_EQ(0, audio_device()->InitPlayout());
841 EXPECT_EQ(0, audio_device()->StartPlayout());
842 EXPECT_EQ(0, audio_device()->StopPlayout());
843 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
844 }
845
846 // Verify that calling StopRecording() will leave us in an uninitialized state
847 // which will require a new call to InitRecording(). This test does not call
848 // StartRecording() while being uninitialized since doing so will hit a
849 // RTC_DCHECK and death tests are not supported on Android.
TEST_F(AudioDeviceTest,StopRecordingRequiresInitToRestart)850 TEST_F(AudioDeviceTest, StopRecordingRequiresInitToRestart) {
851 EXPECT_EQ(0, audio_device()->InitRecording());
852 EXPECT_EQ(0, audio_device()->StartRecording());
853 EXPECT_EQ(0, audio_device()->StopRecording());
854 EXPECT_FALSE(audio_device()->RecordingIsInitialized());
855 }
856
857 // Start playout and verify that the native audio layer starts asking for real
858 // audio samples to play out using the NeedMorePlayData callback.
TEST_F(AudioDeviceTest,StartPlayoutVerifyCallbacks)859 TEST_F(AudioDeviceTest, StartPlayoutVerifyCallbacks) {
860 MockAudioTransportAndroid mock(kPlayout);
861 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
862 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(),
863 kBytesPerSample,
864 playout_channels(),
865 playout_sample_rate(),
866 NotNull(),
867 _, _, _))
868 .Times(AtLeast(kNumCallbacks));
869 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
870 StartPlayout();
871 test_is_done_->Wait(kTestTimeOutInMilliseconds);
872 StopPlayout();
873 }
874
875 // Start recording and verify that the native audio layer starts feeding real
876 // audio samples via the RecordedDataIsAvailable callback.
TEST_F(AudioDeviceTest,StartRecordingVerifyCallbacks)877 TEST_F(AudioDeviceTest, StartRecordingVerifyCallbacks) {
878 MockAudioTransportAndroid mock(kRecording);
879 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
880 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(),
881 record_frames_per_10ms_buffer(),
882 kBytesPerSample,
883 record_channels(),
884 record_sample_rate(),
885 total_delay_ms(),
886 0,
887 0,
888 false,
889 _))
890 .Times(AtLeast(kNumCallbacks));
891
892 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
893 StartRecording();
894 test_is_done_->Wait(kTestTimeOutInMilliseconds);
895 StopRecording();
896 }
897
898
899 // Start playout and recording (full-duplex audio) and verify that audio is
900 // active in both directions.
TEST_F(AudioDeviceTest,StartPlayoutAndRecordingVerifyCallbacks)901 TEST_F(AudioDeviceTest, StartPlayoutAndRecordingVerifyCallbacks) {
902 MockAudioTransportAndroid mock(kPlayout | kRecording);
903 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
904 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(),
905 kBytesPerSample,
906 playout_channels(),
907 playout_sample_rate(),
908 NotNull(),
909 _, _, _))
910 .Times(AtLeast(kNumCallbacks));
911 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(),
912 record_frames_per_10ms_buffer(),
913 kBytesPerSample,
914 record_channels(),
915 record_sample_rate(),
916 total_delay_ms(),
917 0,
918 0,
919 false,
920 _))
921 .Times(AtLeast(kNumCallbacks));
922 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
923 StartPlayout();
924 StartRecording();
925 test_is_done_->Wait(kTestTimeOutInMilliseconds);
926 StopRecording();
927 StopPlayout();
928 }
929
930 // Start playout and read audio from an external PCM file when the audio layer
931 // asks for data to play out. Real audio is played out in this test but it does
932 // not contain any explicit verification that the audio quality is perfect.
TEST_F(AudioDeviceTest,RunPlayoutWithFileAsSource)933 TEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) {
934 // TODO(henrika): extend test when mono output is supported.
935 EXPECT_EQ(1u, playout_channels());
936 NiceMock<MockAudioTransportAndroid> mock(kPlayout);
937 const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond;
938 std::string file_name = GetFileName(playout_sample_rate());
939 std::unique_ptr<FileAudioStream> file_audio_stream(
940 new FileAudioStream(num_callbacks, file_name, playout_sample_rate()));
941 mock.HandleCallbacks(test_is_done_.get(),
942 file_audio_stream.get(),
943 num_callbacks);
944 // SetMaxPlayoutVolume();
945 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
946 StartPlayout();
947 test_is_done_->Wait(kTestTimeOutInMilliseconds);
948 StopPlayout();
949 }
950
951 // Start playout and recording and store recorded data in an intermediate FIFO
952 // buffer from which the playout side then reads its samples in the same order
953 // as they were stored. Under ideal circumstances, a callback sequence would
954 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-'
955 // means 'packet played'. Under such conditions, the FIFO would only contain
956 // one packet on average. However, under more realistic conditions, the size
957 // of the FIFO will vary more due to an unbalance between the two sides.
958 // This test tries to verify that the device maintains a balanced callback-
959 // sequence by running in loopback for ten seconds while measuring the size
960 // (max and average) of the FIFO. The size of the FIFO is increased by the
961 // recording side and decreased by the playout side.
962 // TODO(henrika): tune the final test parameters after running tests on several
963 // different devices.
TEST_F(AudioDeviceTest,RunPlayoutAndRecordingInFullDuplex)964 TEST_F(AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) {
965 EXPECT_EQ(record_channels(), playout_channels());
966 EXPECT_EQ(record_sample_rate(), playout_sample_rate());
967 NiceMock<MockAudioTransportAndroid> mock(kPlayout | kRecording);
968 std::unique_ptr<FifoAudioStream> fifo_audio_stream(
969 new FifoAudioStream(playout_frames_per_10ms_buffer()));
970 mock.HandleCallbacks(test_is_done_.get(),
971 fifo_audio_stream.get(),
972 kFullDuplexTimeInSec * kNumCallbacksPerSecond);
973 SetMaxPlayoutVolume();
974 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
975 StartRecording();
976 StartPlayout();
977 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds,
978 1000 * kFullDuplexTimeInSec));
979 StopPlayout();
980 StopRecording();
981
982 // These thresholds are set rather high to accomodate differences in hardware
983 // in several devices, so this test can be used in swarming.
984 // See http://bugs.webrtc.org/6464
985 EXPECT_LE(fifo_audio_stream->average_size(), 60u);
986 EXPECT_LE(fifo_audio_stream->largest_size(), 70u);
987 }
988
989 // Measures loopback latency and reports the min, max and average values for
990 // a full duplex audio session.
991 // The latency is measured like so:
992 // - Insert impulses periodically on the output side.
993 // - Detect the impulses on the input side.
994 // - Measure the time difference between the transmit time and receive time.
995 // - Store time differences in a vector and calculate min, max and average.
996 // This test requires a special hardware called Audio Loopback Dongle.
997 // See http://source.android.com/devices/audio/loopback.html for details.
TEST_F(AudioDeviceTest,DISABLED_MeasureLoopbackLatency)998 TEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) {
999 EXPECT_EQ(record_channels(), playout_channels());
1000 EXPECT_EQ(record_sample_rate(), playout_sample_rate());
1001 NiceMock<MockAudioTransportAndroid> mock(kPlayout | kRecording);
1002 std::unique_ptr<LatencyMeasuringAudioStream> latency_audio_stream(
1003 new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer()));
1004 mock.HandleCallbacks(test_is_done_.get(),
1005 latency_audio_stream.get(),
1006 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond);
1007 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1008 SetMaxPlayoutVolume();
1009 DisableBuiltInAECIfAvailable();
1010 StartRecording();
1011 StartPlayout();
1012 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds,
1013 1000 * kMeasureLatencyTimeInSec));
1014 StopPlayout();
1015 StopRecording();
1016 // Verify that the correct number of transmitted impulses are detected.
1017 EXPECT_EQ(latency_audio_stream->num_latency_values(),
1018 static_cast<size_t>(
1019 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1));
1020 latency_audio_stream->PrintResults();
1021 }
1022
1023 } // namespace webrtc
1024