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 <numeric>
15 #include <string>
16 #include <vector>
17
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "webrtc/base/arraysize.h"
21 #include "webrtc/base/criticalsection.h"
22 #include "webrtc/base/format_macros.h"
23 #include "webrtc/base/scoped_ptr.h"
24 #include "webrtc/base/scoped_ref_ptr.h"
25 #include "webrtc/modules/audio_device/android/audio_common.h"
26 #include "webrtc/modules/audio_device/android/audio_manager.h"
27 #include "webrtc/modules/audio_device/android/build_info.h"
28 #include "webrtc/modules/audio_device/android/ensure_initialized.h"
29 #include "webrtc/modules/audio_device/audio_device_impl.h"
30 #include "webrtc/modules/audio_device/include/audio_device.h"
31 #include "webrtc/system_wrappers/include/clock.h"
32 #include "webrtc/system_wrappers/include/event_wrapper.h"
33 #include "webrtc/system_wrappers/include/sleep.h"
34 #include "webrtc/test/testsupport/fileutils.h"
35
36 using std::cout;
37 using std::endl;
38 using ::testing::_;
39 using ::testing::AtLeast;
40 using ::testing::Gt;
41 using ::testing::Invoke;
42 using ::testing::NiceMock;
43 using ::testing::NotNull;
44 using ::testing::Return;
45 using ::testing::TestWithParam;
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 rtc::scoped_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 rtc::scoped_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 : clock_(Clock::GetRealTimeClock()),
256 frames_per_buffer_(frames_per_buffer),
257 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
258 play_count_(0),
259 rec_count_(0),
260 pulse_time_(0) {
261 }
262
263 // Insert periodic impulses in first two samples of |destination|.
Read(void * destination,size_t num_frames)264 void Read(void* destination, size_t num_frames) override {
265 ASSERT_EQ(num_frames, frames_per_buffer_);
266 if (play_count_ == 0) {
267 PRINT("[");
268 }
269 play_count_++;
270 memset(destination, 0, bytes_per_buffer_);
271 if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) {
272 if (pulse_time_ == 0) {
273 pulse_time_ = clock_->TimeInMilliseconds();
274 }
275 PRINT(".");
276 const int16_t impulse = std::numeric_limits<int16_t>::max();
277 int16_t* ptr16 = static_cast<int16_t*> (destination);
278 for (size_t i = 0; i < 2; ++i) {
279 ptr16[i] = impulse;
280 }
281 }
282 }
283
284 // Detect received impulses in |source|, derive time between transmission and
285 // detection and add the calculated delay to list of latencies.
Write(const void * source,size_t num_frames)286 void Write(const void* source, size_t num_frames) override {
287 ASSERT_EQ(num_frames, frames_per_buffer_);
288 rec_count_++;
289 if (pulse_time_ == 0) {
290 // Avoid detection of new impulse response until a new impulse has
291 // been transmitted (sets |pulse_time_| to value larger than zero).
292 return;
293 }
294 const int16_t* ptr16 = static_cast<const int16_t*> (source);
295 std::vector<int16_t> vec(ptr16, ptr16 + num_frames);
296 // Find max value in the audio buffer.
297 int max = *std::max_element(vec.begin(), vec.end());
298 // Find index (element position in vector) of the max element.
299 int index_of_max = std::distance(vec.begin(),
300 std::find(vec.begin(), vec.end(),
301 max));
302 if (max > kImpulseThreshold) {
303 PRINTD("(%d,%d)", max, index_of_max);
304 int64_t now_time = clock_->TimeInMilliseconds();
305 int extra_delay = IndexToMilliseconds(static_cast<double> (index_of_max));
306 PRINTD("[%d]", static_cast<int> (now_time - pulse_time_));
307 PRINTD("[%d]", extra_delay);
308 // Total latency is the difference between transmit time and detection
309 // tome plus the extra delay within the buffer in which we detected the
310 // received impulse. It is transmitted at sample 0 but can be received
311 // at sample N where N > 0. The term |extra_delay| accounts for N and it
312 // is a value between 0 and 10ms.
313 latencies_.push_back(now_time - pulse_time_ + extra_delay);
314 pulse_time_ = 0;
315 } else {
316 PRINTD("-");
317 }
318 }
319
num_latency_values() const320 size_t num_latency_values() const {
321 return latencies_.size();
322 }
323
min_latency() const324 int min_latency() const {
325 if (latencies_.empty())
326 return 0;
327 return *std::min_element(latencies_.begin(), latencies_.end());
328 }
329
max_latency() const330 int max_latency() const {
331 if (latencies_.empty())
332 return 0;
333 return *std::max_element(latencies_.begin(), latencies_.end());
334 }
335
average_latency() const336 int average_latency() const {
337 if (latencies_.empty())
338 return 0;
339 return 0.5 + static_cast<double> (
340 std::accumulate(latencies_.begin(), latencies_.end(), 0)) /
341 latencies_.size();
342 }
343
PrintResults() const344 void PrintResults() const {
345 PRINT("] ");
346 for (auto it = latencies_.begin(); it != latencies_.end(); ++it) {
347 PRINT("%d ", *it);
348 }
349 PRINT("\n");
350 PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag,
351 min_latency(), max_latency(), average_latency());
352 }
353
IndexToMilliseconds(double index) const354 int IndexToMilliseconds(double index) const {
355 return static_cast<int>(10.0 * (index / frames_per_buffer_) + 0.5);
356 }
357
358 private:
359 Clock* clock_;
360 const size_t frames_per_buffer_;
361 const size_t bytes_per_buffer_;
362 size_t play_count_;
363 size_t rec_count_;
364 int64_t pulse_time_;
365 std::vector<int> latencies_;
366 };
367
368 // Mocks the AudioTransport object and proxies actions for the two callbacks
369 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations
370 // of AudioStreamInterface.
371 class MockAudioTransport : public AudioTransport {
372 public:
MockAudioTransport(int type)373 explicit MockAudioTransport(int type)
374 : num_callbacks_(0),
375 type_(type),
376 play_count_(0),
377 rec_count_(0),
378 audio_stream_(nullptr) {}
379
~MockAudioTransport()380 virtual ~MockAudioTransport() {}
381
382 MOCK_METHOD10(RecordedDataIsAvailable,
383 int32_t(const void* audioSamples,
384 const size_t nSamples,
385 const size_t nBytesPerSample,
386 const size_t nChannels,
387 const uint32_t samplesPerSec,
388 const uint32_t totalDelayMS,
389 const int32_t clockDrift,
390 const uint32_t currentMicLevel,
391 const bool keyPressed,
392 uint32_t& newMicLevel));
393 MOCK_METHOD8(NeedMorePlayData,
394 int32_t(const size_t nSamples,
395 const size_t nBytesPerSample,
396 const size_t nChannels,
397 const uint32_t samplesPerSec,
398 void* audioSamples,
399 size_t& nSamplesOut,
400 int64_t* elapsed_time_ms,
401 int64_t* ntp_time_ms));
402
403 // Set default actions of the mock object. We are delegating to fake
404 // implementations (of AudioStreamInterface) here.
HandleCallbacks(EventWrapper * test_is_done,AudioStreamInterface * audio_stream,int num_callbacks)405 void HandleCallbacks(EventWrapper* test_is_done,
406 AudioStreamInterface* audio_stream,
407 int num_callbacks) {
408 test_is_done_ = test_is_done;
409 audio_stream_ = audio_stream;
410 num_callbacks_ = num_callbacks;
411 if (play_mode()) {
412 ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _))
413 .WillByDefault(
414 Invoke(this, &MockAudioTransport::RealNeedMorePlayData));
415 }
416 if (rec_mode()) {
417 ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _))
418 .WillByDefault(
419 Invoke(this, &MockAudioTransport::RealRecordedDataIsAvailable));
420 }
421 }
422
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)423 int32_t RealRecordedDataIsAvailable(const void* audioSamples,
424 const size_t nSamples,
425 const size_t nBytesPerSample,
426 const size_t nChannels,
427 const uint32_t samplesPerSec,
428 const uint32_t totalDelayMS,
429 const int32_t clockDrift,
430 const uint32_t currentMicLevel,
431 const bool keyPressed,
432 uint32_t& newMicLevel) {
433 EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks.";
434 rec_count_++;
435 // Process the recorded audio stream if an AudioStreamInterface
436 // implementation exists.
437 if (audio_stream_) {
438 audio_stream_->Write(audioSamples, nSamples);
439 }
440 if (ReceivedEnoughCallbacks()) {
441 test_is_done_->Set();
442 }
443 return 0;
444 }
445
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)446 int32_t RealNeedMorePlayData(const size_t nSamples,
447 const size_t nBytesPerSample,
448 const size_t nChannels,
449 const uint32_t samplesPerSec,
450 void* audioSamples,
451 size_t& nSamplesOut,
452 int64_t* elapsed_time_ms,
453 int64_t* ntp_time_ms) {
454 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks.";
455 play_count_++;
456 nSamplesOut = nSamples;
457 // Read (possibly processed) audio stream samples to be played out if an
458 // AudioStreamInterface implementation exists.
459 if (audio_stream_) {
460 audio_stream_->Read(audioSamples, nSamples);
461 }
462 if (ReceivedEnoughCallbacks()) {
463 test_is_done_->Set();
464 }
465 return 0;
466 }
467
ReceivedEnoughCallbacks()468 bool ReceivedEnoughCallbacks() {
469 bool recording_done = false;
470 if (rec_mode())
471 recording_done = rec_count_ >= num_callbacks_;
472 else
473 recording_done = true;
474
475 bool playout_done = false;
476 if (play_mode())
477 playout_done = play_count_ >= num_callbacks_;
478 else
479 playout_done = true;
480
481 return recording_done && playout_done;
482 }
483
play_mode() const484 bool play_mode() const { return type_ & kPlayout; }
rec_mode() const485 bool rec_mode() const { return type_ & kRecording; }
486
487 private:
488 EventWrapper* test_is_done_;
489 size_t num_callbacks_;
490 int type_;
491 size_t play_count_;
492 size_t rec_count_;
493 AudioStreamInterface* audio_stream_;
494 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream_;
495 };
496
497 // AudioDeviceTest test fixture.
498 class AudioDeviceTest : public ::testing::Test {
499 protected:
AudioDeviceTest()500 AudioDeviceTest()
501 : test_is_done_(EventWrapper::Create()) {
502 // One-time initialization of JVM and application context. Ensures that we
503 // can do calls between C++ and Java. Initializes both Java and OpenSL ES
504 // implementations.
505 webrtc::audiodevicemodule::EnsureInitialized();
506 // Creates an audio device using a default audio layer.
507 audio_device_ = CreateAudioDevice(AudioDeviceModule::kPlatformDefaultAudio);
508 EXPECT_NE(audio_device_.get(), nullptr);
509 EXPECT_EQ(0, audio_device_->Init());
510 playout_parameters_ = audio_manager()->GetPlayoutAudioParameters();
511 record_parameters_ = audio_manager()->GetRecordAudioParameters();
512 build_info_.reset(new BuildInfo());
513 }
~AudioDeviceTest()514 virtual ~AudioDeviceTest() {
515 EXPECT_EQ(0, audio_device_->Terminate());
516 }
517
playout_sample_rate() const518 int playout_sample_rate() const {
519 return playout_parameters_.sample_rate();
520 }
record_sample_rate() const521 int record_sample_rate() const {
522 return record_parameters_.sample_rate();
523 }
playout_channels() const524 size_t playout_channels() const {
525 return playout_parameters_.channels();
526 }
record_channels() const527 size_t record_channels() const {
528 return record_parameters_.channels();
529 }
playout_frames_per_10ms_buffer() const530 size_t playout_frames_per_10ms_buffer() const {
531 return playout_parameters_.frames_per_10ms_buffer();
532 }
record_frames_per_10ms_buffer() const533 size_t record_frames_per_10ms_buffer() const {
534 return record_parameters_.frames_per_10ms_buffer();
535 }
536
total_delay_ms() const537 int total_delay_ms() const {
538 return audio_manager()->GetDelayEstimateInMilliseconds();
539 }
540
audio_device() const541 rtc::scoped_refptr<AudioDeviceModule> audio_device() const {
542 return audio_device_;
543 }
544
audio_device_impl() const545 AudioDeviceModuleImpl* audio_device_impl() const {
546 return static_cast<AudioDeviceModuleImpl*>(audio_device_.get());
547 }
548
audio_manager() const549 AudioManager* audio_manager() const {
550 return audio_device_impl()->GetAndroidAudioManagerForTest();
551 }
552
GetAudioManager(AudioDeviceModule * adm) const553 AudioManager* GetAudioManager(AudioDeviceModule* adm) const {
554 return static_cast<AudioDeviceModuleImpl*>(adm)->
555 GetAndroidAudioManagerForTest();
556 }
557
audio_device_buffer() const558 AudioDeviceBuffer* audio_device_buffer() const {
559 return audio_device_impl()->GetAudioDeviceBuffer();
560 }
561
CreateAudioDevice(AudioDeviceModule::AudioLayer audio_layer)562 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDevice(
563 AudioDeviceModule::AudioLayer audio_layer) {
564 rtc::scoped_refptr<AudioDeviceModule> module(
565 AudioDeviceModuleImpl::Create(0, audio_layer));
566 return module;
567 }
568
569 // Returns file name relative to the resource root given a sample rate.
GetFileName(int sample_rate)570 std::string GetFileName(int sample_rate) {
571 EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100);
572 char fname[64];
573 snprintf(fname,
574 sizeof(fname),
575 "audio_device/audio_short%d",
576 sample_rate / 1000);
577 std::string file_name(webrtc::test::ResourcePath(fname, "pcm"));
578 EXPECT_TRUE(test::FileExists(file_name));
579 #ifdef ENABLE_PRINTF
580 PRINT("file name: %s\n", file_name.c_str());
581 const size_t bytes = test::GetFileSize(file_name);
582 PRINT("file size: %" PRIuS " [bytes]\n", bytes);
583 PRINT("file size: %" PRIuS " [samples]\n", bytes / kBytesPerSample);
584 const int seconds =
585 static_cast<int>(bytes / (sample_rate * kBytesPerSample));
586 PRINT("file size: %d [secs]\n", seconds);
587 PRINT("file size: %" PRIuS " [callbacks]\n",
588 seconds * kNumCallbacksPerSecond);
589 #endif
590 return file_name;
591 }
592
GetActiveAudioLayer() const593 AudioDeviceModule::AudioLayer GetActiveAudioLayer() const {
594 AudioDeviceModule::AudioLayer audio_layer;
595 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer));
596 return audio_layer;
597 }
598
TestDelayOnAudioLayer(const AudioDeviceModule::AudioLayer & layer_to_test)599 int TestDelayOnAudioLayer(
600 const AudioDeviceModule::AudioLayer& layer_to_test) {
601 rtc::scoped_refptr<AudioDeviceModule> audio_device;
602 audio_device = CreateAudioDevice(layer_to_test);
603 EXPECT_NE(audio_device.get(), nullptr);
604 AudioManager* audio_manager = GetAudioManager(audio_device.get());
605 EXPECT_NE(audio_manager, nullptr);
606 return audio_manager->GetDelayEstimateInMilliseconds();
607 }
608
TestActiveAudioLayer(const AudioDeviceModule::AudioLayer & layer_to_test)609 AudioDeviceModule::AudioLayer TestActiveAudioLayer(
610 const AudioDeviceModule::AudioLayer& layer_to_test) {
611 rtc::scoped_refptr<AudioDeviceModule> audio_device;
612 audio_device = CreateAudioDevice(layer_to_test);
613 EXPECT_NE(audio_device.get(), nullptr);
614 AudioDeviceModule::AudioLayer active;
615 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&active));
616 return active;
617 }
618
DisableTestForThisDevice(const std::string & model)619 bool DisableTestForThisDevice(const std::string& model) {
620 return (build_info_->GetDeviceModel() == model);
621 }
622
623 // Volume control is currently only supported for the Java output audio layer.
624 // For OpenSL ES, the internal stream volume is always on max level and there
625 // is no need for this test to set it to max.
AudioLayerSupportsVolumeControl() const626 bool AudioLayerSupportsVolumeControl() const {
627 return GetActiveAudioLayer() == AudioDeviceModule::kAndroidJavaAudio;
628 }
629
SetMaxPlayoutVolume()630 void SetMaxPlayoutVolume() {
631 if (!AudioLayerSupportsVolumeControl())
632 return;
633 uint32_t max_volume;
634 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume));
635 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume));
636 }
637
DisableBuiltInAECIfAvailable()638 void DisableBuiltInAECIfAvailable() {
639 if (audio_device()->BuiltInAECIsAvailable()) {
640 EXPECT_EQ(0, audio_device()->EnableBuiltInAEC(false));
641 }
642 }
643
StartPlayout()644 void StartPlayout() {
645 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
646 EXPECT_FALSE(audio_device()->Playing());
647 EXPECT_EQ(0, audio_device()->InitPlayout());
648 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
649 EXPECT_EQ(0, audio_device()->StartPlayout());
650 EXPECT_TRUE(audio_device()->Playing());
651 }
652
StopPlayout()653 void StopPlayout() {
654 EXPECT_EQ(0, audio_device()->StopPlayout());
655 EXPECT_FALSE(audio_device()->Playing());
656 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
657 }
658
StartRecording()659 void StartRecording() {
660 EXPECT_FALSE(audio_device()->RecordingIsInitialized());
661 EXPECT_FALSE(audio_device()->Recording());
662 EXPECT_EQ(0, audio_device()->InitRecording());
663 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
664 EXPECT_EQ(0, audio_device()->StartRecording());
665 EXPECT_TRUE(audio_device()->Recording());
666 }
667
StopRecording()668 void StopRecording() {
669 EXPECT_EQ(0, audio_device()->StopRecording());
670 EXPECT_FALSE(audio_device()->Recording());
671 }
672
GetMaxSpeakerVolume() const673 int GetMaxSpeakerVolume() const {
674 uint32_t max_volume(0);
675 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume));
676 return max_volume;
677 }
678
GetMinSpeakerVolume() const679 int GetMinSpeakerVolume() const {
680 uint32_t min_volume(0);
681 EXPECT_EQ(0, audio_device()->MinSpeakerVolume(&min_volume));
682 return min_volume;
683 }
684
GetSpeakerVolume() const685 int GetSpeakerVolume() const {
686 uint32_t volume(0);
687 EXPECT_EQ(0, audio_device()->SpeakerVolume(&volume));
688 return volume;
689 }
690
691 rtc::scoped_ptr<EventWrapper> test_is_done_;
692 rtc::scoped_refptr<AudioDeviceModule> audio_device_;
693 AudioParameters playout_parameters_;
694 AudioParameters record_parameters_;
695 rtc::scoped_ptr<BuildInfo> build_info_;
696 };
697
TEST_F(AudioDeviceTest,ConstructDestruct)698 TEST_F(AudioDeviceTest, ConstructDestruct) {
699 // Using the test fixture to create and destruct the audio device module.
700 }
701
702 // We always ask for a default audio layer when the ADM is constructed. But the
703 // ADM will then internally set the best suitable combination of audio layers,
704 // for input and output based on if low-latency output audio in combination
705 // with OpenSL ES is supported or not. This test ensures that the correct
706 // selection is done.
TEST_F(AudioDeviceTest,VerifyDefaultAudioLayer)707 TEST_F(AudioDeviceTest, VerifyDefaultAudioLayer) {
708 const AudioDeviceModule::AudioLayer audio_layer = GetActiveAudioLayer();
709 bool low_latency_output = audio_manager()->IsLowLatencyPlayoutSupported();
710 AudioDeviceModule::AudioLayer expected_audio_layer = low_latency_output ?
711 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio :
712 AudioDeviceModule::kAndroidJavaAudio;
713 EXPECT_EQ(expected_audio_layer, audio_layer);
714 }
715
716 // Verify that it is possible to explicitly create the two types of supported
717 // ADMs. These two tests overrides the default selection of native audio layer
718 // by ignoring if the device supports low-latency output or not.
TEST_F(AudioDeviceTest,CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo)719 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo) {
720 AudioDeviceModule::AudioLayer expected_layer =
721 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio;
722 AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer(
723 expected_layer);
724 EXPECT_EQ(expected_layer, active_layer);
725 }
726
TEST_F(AudioDeviceTest,CorrectAudioLayerIsUsedForJavaInBothDirections)727 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForJavaInBothDirections) {
728 AudioDeviceModule::AudioLayer expected_layer =
729 AudioDeviceModule::kAndroidJavaAudio;
730 AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer(
731 expected_layer);
732 EXPECT_EQ(expected_layer, active_layer);
733 }
734
735 // The Android ADM supports two different delay reporting modes. One for the
736 // low-latency output path (in combination with OpenSL ES), and one for the
737 // high-latency output path (Java backends in both directions). These two tests
738 // verifies that the audio manager reports correct delay estimate given the
739 // selected audio layer. Note that, this delay estimate will only be utilized
740 // if the HW AEC is disabled.
TEST_F(AudioDeviceTest,UsesCorrectDelayEstimateForHighLatencyOutputPath)741 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForHighLatencyOutputPath) {
742 EXPECT_EQ(kHighLatencyModeDelayEstimateInMilliseconds,
743 TestDelayOnAudioLayer(AudioDeviceModule::kAndroidJavaAudio));
744 }
745
TEST_F(AudioDeviceTest,UsesCorrectDelayEstimateForLowLatencyOutputPath)746 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForLowLatencyOutputPath) {
747 EXPECT_EQ(kLowLatencyModeDelayEstimateInMilliseconds,
748 TestDelayOnAudioLayer(
749 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio));
750 }
751
752 // Ensure that the ADM internal audio device buffer is configured to use the
753 // correct set of parameters.
TEST_F(AudioDeviceTest,VerifyAudioDeviceBufferParameters)754 TEST_F(AudioDeviceTest, VerifyAudioDeviceBufferParameters) {
755 EXPECT_EQ(playout_parameters_.sample_rate(),
756 audio_device_buffer()->PlayoutSampleRate());
757 EXPECT_EQ(record_parameters_.sample_rate(),
758 audio_device_buffer()->RecordingSampleRate());
759 EXPECT_EQ(playout_parameters_.channels(),
760 audio_device_buffer()->PlayoutChannels());
761 EXPECT_EQ(record_parameters_.channels(),
762 audio_device_buffer()->RecordingChannels());
763 }
764
765
TEST_F(AudioDeviceTest,InitTerminate)766 TEST_F(AudioDeviceTest, InitTerminate) {
767 // Initialization is part of the test fixture.
768 EXPECT_TRUE(audio_device()->Initialized());
769 EXPECT_EQ(0, audio_device()->Terminate());
770 EXPECT_FALSE(audio_device()->Initialized());
771 }
772
TEST_F(AudioDeviceTest,Devices)773 TEST_F(AudioDeviceTest, Devices) {
774 // Device enumeration is not supported. Verify fixed values only.
775 EXPECT_EQ(1, audio_device()->PlayoutDevices());
776 EXPECT_EQ(1, audio_device()->RecordingDevices());
777 }
778
TEST_F(AudioDeviceTest,SpeakerVolumeShouldBeAvailable)779 TEST_F(AudioDeviceTest, SpeakerVolumeShouldBeAvailable) {
780 // The OpenSL ES output audio path does not support volume control.
781 if (!AudioLayerSupportsVolumeControl())
782 return;
783 bool available;
784 EXPECT_EQ(0, audio_device()->SpeakerVolumeIsAvailable(&available));
785 EXPECT_TRUE(available);
786 }
787
TEST_F(AudioDeviceTest,MaxSpeakerVolumeIsPositive)788 TEST_F(AudioDeviceTest, MaxSpeakerVolumeIsPositive) {
789 // The OpenSL ES output audio path does not support volume control.
790 if (!AudioLayerSupportsVolumeControl())
791 return;
792 StartPlayout();
793 EXPECT_GT(GetMaxSpeakerVolume(), 0);
794 StopPlayout();
795 }
796
TEST_F(AudioDeviceTest,MinSpeakerVolumeIsZero)797 TEST_F(AudioDeviceTest, MinSpeakerVolumeIsZero) {
798 // The OpenSL ES output audio path does not support volume control.
799 if (!AudioLayerSupportsVolumeControl())
800 return;
801 EXPECT_EQ(GetMinSpeakerVolume(), 0);
802 }
803
TEST_F(AudioDeviceTest,DefaultSpeakerVolumeIsWithinMinMax)804 TEST_F(AudioDeviceTest, DefaultSpeakerVolumeIsWithinMinMax) {
805 // The OpenSL ES output audio path does not support volume control.
806 if (!AudioLayerSupportsVolumeControl())
807 return;
808 const int default_volume = GetSpeakerVolume();
809 EXPECT_GE(default_volume, GetMinSpeakerVolume());
810 EXPECT_LE(default_volume, GetMaxSpeakerVolume());
811 }
812
TEST_F(AudioDeviceTest,SetSpeakerVolumeActuallySetsVolume)813 TEST_F(AudioDeviceTest, SetSpeakerVolumeActuallySetsVolume) {
814 // The OpenSL ES output audio path does not support volume control.
815 if (!AudioLayerSupportsVolumeControl())
816 return;
817 const int default_volume = GetSpeakerVolume();
818 const int max_volume = GetMaxSpeakerVolume();
819 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume));
820 int new_volume = GetSpeakerVolume();
821 EXPECT_EQ(new_volume, max_volume);
822 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(default_volume));
823 }
824
825 // Tests that playout can be initiated, started and stopped. No audio callback
826 // is registered in this test.
827 // Flaky on our trybots makes this test unusable.
828 // https://code.google.com/p/webrtc/issues/detail?id=5046
TEST_F(AudioDeviceTest,DISABLED_StartStopPlayout)829 TEST_F(AudioDeviceTest, DISABLED_StartStopPlayout) {
830 StartPlayout();
831 StopPlayout();
832 StartPlayout();
833 StopPlayout();
834 }
835
836 // Tests that recording can be initiated, started and stopped. No audio callback
837 // is registered in this test.
TEST_F(AudioDeviceTest,StartStopRecording)838 TEST_F(AudioDeviceTest, StartStopRecording) {
839 StartRecording();
840 StopRecording();
841 StartRecording();
842 StopRecording();
843 }
844
845 // Verify that calling StopPlayout() will leave us in an uninitialized state
846 // which will require a new call to InitPlayout(). This test does not call
847 // StartPlayout() while being uninitialized since doing so will hit a
848 // RTC_DCHECK.
TEST_F(AudioDeviceTest,StopPlayoutRequiresInitToRestart)849 TEST_F(AudioDeviceTest, StopPlayoutRequiresInitToRestart) {
850 EXPECT_EQ(0, audio_device()->InitPlayout());
851 EXPECT_EQ(0, audio_device()->StartPlayout());
852 EXPECT_EQ(0, audio_device()->StopPlayout());
853 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
854 }
855
856 // Start playout and verify that the native audio layer starts asking for real
857 // audio samples to play out using the NeedMorePlayData callback.
TEST_F(AudioDeviceTest,StartPlayoutVerifyCallbacks)858 TEST_F(AudioDeviceTest, StartPlayoutVerifyCallbacks) {
859 MockAudioTransport mock(kPlayout);
860 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
861 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(),
862 kBytesPerSample,
863 playout_channels(),
864 playout_sample_rate(),
865 NotNull(),
866 _, _, _))
867 .Times(AtLeast(kNumCallbacks));
868 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
869 StartPlayout();
870 test_is_done_->Wait(kTestTimeOutInMilliseconds);
871 StopPlayout();
872 }
873
874 // Start recording and verify that the native audio layer starts feeding real
875 // audio samples via the RecordedDataIsAvailable callback.
TEST_F(AudioDeviceTest,StartRecordingVerifyCallbacks)876 TEST_F(AudioDeviceTest, StartRecordingVerifyCallbacks) {
877 MockAudioTransport mock(kRecording);
878 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
879 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(),
880 record_frames_per_10ms_buffer(),
881 kBytesPerSample,
882 record_channels(),
883 record_sample_rate(),
884 total_delay_ms(),
885 0,
886 0,
887 false,
888 _))
889 .Times(AtLeast(kNumCallbacks));
890
891 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
892 StartRecording();
893 test_is_done_->Wait(kTestTimeOutInMilliseconds);
894 StopRecording();
895 }
896
897
898 // Start playout and recording (full-duplex audio) and verify that audio is
899 // active in both directions.
TEST_F(AudioDeviceTest,StartPlayoutAndRecordingVerifyCallbacks)900 TEST_F(AudioDeviceTest, StartPlayoutAndRecordingVerifyCallbacks) {
901 MockAudioTransport mock(kPlayout | kRecording);
902 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks);
903 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(),
904 kBytesPerSample,
905 playout_channels(),
906 playout_sample_rate(),
907 NotNull(),
908 _, _, _))
909 .Times(AtLeast(kNumCallbacks));
910 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(),
911 record_frames_per_10ms_buffer(),
912 kBytesPerSample,
913 record_channels(),
914 record_sample_rate(),
915 total_delay_ms(),
916 0,
917 0,
918 false,
919 _))
920 .Times(AtLeast(kNumCallbacks));
921 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
922 StartPlayout();
923 StartRecording();
924 test_is_done_->Wait(kTestTimeOutInMilliseconds);
925 StopRecording();
926 StopPlayout();
927 }
928
929 // Start playout and read audio from an external PCM file when the audio layer
930 // asks for data to play out. Real audio is played out in this test but it does
931 // not contain any explicit verification that the audio quality is perfect.
TEST_F(AudioDeviceTest,RunPlayoutWithFileAsSource)932 TEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) {
933 // TODO(henrika): extend test when mono output is supported.
934 EXPECT_EQ(1u, playout_channels());
935 NiceMock<MockAudioTransport> mock(kPlayout);
936 const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond;
937 std::string file_name = GetFileName(playout_sample_rate());
938 rtc::scoped_ptr<FileAudioStream> file_audio_stream(
939 new FileAudioStream(num_callbacks, file_name, playout_sample_rate()));
940 mock.HandleCallbacks(test_is_done_.get(),
941 file_audio_stream.get(),
942 num_callbacks);
943 // SetMaxPlayoutVolume();
944 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
945 StartPlayout();
946 test_is_done_->Wait(kTestTimeOutInMilliseconds);
947 StopPlayout();
948 }
949
950 // Start playout and recording and store recorded data in an intermediate FIFO
951 // buffer from which the playout side then reads its samples in the same order
952 // as they were stored. Under ideal circumstances, a callback sequence would
953 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-'
954 // means 'packet played'. Under such conditions, the FIFO would only contain
955 // one packet on average. However, under more realistic conditions, the size
956 // of the FIFO will vary more due to an unbalance between the two sides.
957 // This test tries to verify that the device maintains a balanced callback-
958 // sequence by running in loopback for ten seconds while measuring the size
959 // (max and average) of the FIFO. The size of the FIFO is increased by the
960 // recording side and decreased by the playout side.
961 // TODO(henrika): tune the final test parameters after running tests on several
962 // different devices.
TEST_F(AudioDeviceTest,RunPlayoutAndRecordingInFullDuplex)963 TEST_F(AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) {
964 EXPECT_EQ(record_channels(), playout_channels());
965 EXPECT_EQ(record_sample_rate(), playout_sample_rate());
966 NiceMock<MockAudioTransport> mock(kPlayout | kRecording);
967 rtc::scoped_ptr<FifoAudioStream> fifo_audio_stream(
968 new FifoAudioStream(playout_frames_per_10ms_buffer()));
969 mock.HandleCallbacks(test_is_done_.get(),
970 fifo_audio_stream.get(),
971 kFullDuplexTimeInSec * kNumCallbacksPerSecond);
972 SetMaxPlayoutVolume();
973 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
974 StartRecording();
975 StartPlayout();
976 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds,
977 1000 * kFullDuplexTimeInSec));
978 StopPlayout();
979 StopRecording();
980 EXPECT_LE(fifo_audio_stream->average_size(), 10u);
981 EXPECT_LE(fifo_audio_stream->largest_size(), 20u);
982 }
983
984 // Measures loopback latency and reports the min, max and average values for
985 // a full duplex audio session.
986 // The latency is measured like so:
987 // - Insert impulses periodically on the output side.
988 // - Detect the impulses on the input side.
989 // - Measure the time difference between the transmit time and receive time.
990 // - Store time differences in a vector and calculate min, max and average.
991 // This test requires a special hardware called Audio Loopback Dongle.
992 // See http://source.android.com/devices/audio/loopback.html for details.
TEST_F(AudioDeviceTest,DISABLED_MeasureLoopbackLatency)993 TEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) {
994 EXPECT_EQ(record_channels(), playout_channels());
995 EXPECT_EQ(record_sample_rate(), playout_sample_rate());
996 NiceMock<MockAudioTransport> mock(kPlayout | kRecording);
997 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream(
998 new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer()));
999 mock.HandleCallbacks(test_is_done_.get(),
1000 latency_audio_stream.get(),
1001 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond);
1002 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1003 SetMaxPlayoutVolume();
1004 DisableBuiltInAECIfAvailable();
1005 StartRecording();
1006 StartPlayout();
1007 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds,
1008 1000 * kMeasureLatencyTimeInSec));
1009 StopPlayout();
1010 StopRecording();
1011 // Verify that the correct number of transmitted impulses are detected.
1012 EXPECT_EQ(latency_audio_stream->num_latency_values(),
1013 static_cast<size_t>(
1014 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1));
1015 latency_audio_stream->PrintResults();
1016 }
1017
1018 } // namespace webrtc
1019