1 /*
2 * Copyright (c) 2018 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 <list>
12 #include <memory>
13 #include <numeric>
14
15 #include "api/scoped_refptr.h"
16 #include "modules/audio_device/include/audio_device.h"
17 #include "modules/audio_device/include/mock_audio_transport.h"
18 #include "rtc_base/arraysize.h"
19 #include "rtc_base/critical_section.h"
20 #include "rtc_base/event.h"
21 #include "rtc_base/format_macros.h"
22 #include "rtc_base/time_utils.h"
23 #include "sdk/android/generated_native_unittests_jni/BuildInfo_jni.h"
24 #include "sdk/android/native_api/audio_device_module/audio_device_android.h"
25 #include "sdk/android/native_unittests/application_context_provider.h"
26 #include "sdk/android/src/jni/audio_device/audio_common.h"
27 #include "sdk/android/src/jni/audio_device/audio_device_module.h"
28 #include "sdk/android/src/jni/audio_device/opensles_common.h"
29 #include "sdk/android/src/jni/jni_helpers.h"
30 #include "test/gmock.h"
31 #include "test/gtest.h"
32 #include "test/testsupport/file_utils.h"
33
34 using std::cout;
35 using std::endl;
36 using ::testing::_;
37 using ::testing::AtLeast;
38 using ::testing::Gt;
39 using ::testing::Invoke;
40 using ::testing::NiceMock;
41 using ::testing::NotNull;
42 using ::testing::Return;
43
44 // #define ENABLE_DEBUG_PRINTF
45 #ifdef ENABLE_DEBUG_PRINTF
46 #define PRINTD(...) fprintf(stderr, __VA_ARGS__);
47 #else
48 #define PRINTD(...) ((void)0)
49 #endif
50 #define PRINT(...) fprintf(stderr, __VA_ARGS__);
51
52 namespace webrtc {
53
54 namespace jni {
55
56 // Number of callbacks (input or output) the tests waits for before we set
57 // an event indicating that the test was OK.
58 static const size_t kNumCallbacks = 10;
59 // Max amount of time we wait for an event to be set while counting callbacks.
60 static const int kTestTimeOutInMilliseconds = 10 * 1000;
61 // Average number of audio callbacks per second assuming 10ms packet size.
62 static const size_t kNumCallbacksPerSecond = 100;
63 // Play out a test file during this time (unit is in seconds).
64 static const int kFilePlayTimeInSec = 5;
65 static const size_t kBitsPerSample = 16;
66 static const size_t kBytesPerSample = kBitsPerSample / 8;
67 // Run the full-duplex test during this time (unit is in seconds).
68 // Note that first |kNumIgnoreFirstCallbacks| are ignored.
69 static const int kFullDuplexTimeInSec = 5;
70 // Wait for the callback sequence to stabilize by ignoring this amount of the
71 // initial callbacks (avoids initial FIFO access).
72 // Only used in the RunPlayoutAndRecordingInFullDuplex test.
73 static const size_t kNumIgnoreFirstCallbacks = 50;
74 // Sets the number of impulses per second in the latency test.
75 static const int kImpulseFrequencyInHz = 1;
76 // Length of round-trip latency measurements. Number of transmitted impulses
77 // is kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1.
78 static const int kMeasureLatencyTimeInSec = 11;
79 // Utilized in round-trip latency measurements to avoid capturing noise samples.
80 static const int kImpulseThreshold = 1000;
81 static const char kTag[] = "[..........] ";
82
83 enum TransportType {
84 kPlayout = 0x1,
85 kRecording = 0x2,
86 };
87
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
90 // measurements.
91 class AudioStreamInterface {
92 public:
93 virtual void Write(const void* source, size_t num_frames) = 0;
94 virtual void Read(void* destination, size_t num_frames) = 0;
95
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(size_t num_callbacks,
105 const std::string& file_name,
106 int sample_rate)
107 : file_size_in_bytes_(0), sample_rate_(sample_rate), file_pos_(0) {
108 file_size_in_bytes_ = test::GetFileSize(file_name);
109 sample_rate_ = sample_rate;
110 EXPECT_GE(file_size_in_callbacks(), num_callbacks)
111 << "Size of test file is not large enough to last during the test.";
112 const size_t num_16bit_samples =
113 test::GetFileSize(file_name) / kBytesPerSample;
114 file_.reset(new int16_t[num_16bit_samples]);
115 FILE* audio_file = fopen(file_name.c_str(), "rb");
116 EXPECT_NE(audio_file, nullptr);
117 size_t num_samples_read =
118 fread(file_.get(), sizeof(int16_t), num_16bit_samples, audio_file);
119 EXPECT_EQ(num_samples_read, num_16bit_samples);
120 fclose(audio_file);
121 }
122
123 // AudioStreamInterface::Write() is not implemented.
Write(const void * source,size_t num_frames)124 void Write(const void* source, size_t num_frames) override {}
125
126 // Read samples from file stored in memory (at construction) and copy
127 // |num_frames| (<=> 10ms) to the |destination| byte buffer.
Read(void * destination,size_t num_frames)128 void Read(void* destination, size_t num_frames) override {
129 memcpy(destination, static_cast<int16_t*>(&file_[file_pos_]),
130 num_frames * sizeof(int16_t));
131 file_pos_ += num_frames;
132 }
133
file_size_in_seconds() const134 int file_size_in_seconds() const {
135 return static_cast<int>(file_size_in_bytes_ /
136 (kBytesPerSample * sample_rate_));
137 }
file_size_in_callbacks() const138 size_t file_size_in_callbacks() const {
139 return file_size_in_seconds() * kNumCallbacksPerSecond;
140 }
141
142 private:
143 size_t file_size_in_bytes_;
144 int sample_rate_;
145 std::unique_ptr<int16_t[]> file_;
146 size_t file_pos_;
147 };
148
149 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio
150 // buffers of fixed size and allows Write and Read operations. The idea is to
151 // store recorded audio buffers (using Write) and then read (using Read) these
152 // stored buffers with as short delay as possible when the audio layer needs
153 // data to play out. The number of buffers in the FIFO will stabilize under
154 // normal conditions since there will be a balance between Write and Read calls.
155 // The container is a std::list container and access is protected with a lock
156 // since both sides (playout and recording) are driven by its own thread.
157 class FifoAudioStream : public AudioStreamInterface {
158 public:
FifoAudioStream(size_t frames_per_buffer)159 explicit FifoAudioStream(size_t frames_per_buffer)
160 : frames_per_buffer_(frames_per_buffer),
161 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
162 fifo_(new AudioBufferList),
163 largest_size_(0),
164 total_written_elements_(0),
165 write_count_(0) {
166 EXPECT_NE(fifo_.get(), nullptr);
167 }
168
~FifoAudioStream()169 ~FifoAudioStream() { Flush(); }
170
171 // Allocate new memory, copy |num_frames| samples from |source| into memory
172 // and add pointer to the memory location to end of the list.
173 // Increases the size of the FIFO by one element.
Write(const void * source,size_t num_frames)174 void Write(const void* source, size_t num_frames) override {
175 ASSERT_EQ(num_frames, frames_per_buffer_);
176 PRINTD("+");
177 if (write_count_++ < kNumIgnoreFirstCallbacks) {
178 return;
179 }
180 int16_t* memory = new int16_t[frames_per_buffer_];
181 memcpy(static_cast<int16_t*>(&memory[0]), source, bytes_per_buffer_);
182 rtc::CritScope lock(&lock_);
183 fifo_->push_back(memory);
184 const size_t size = fifo_->size();
185 if (size > largest_size_) {
186 largest_size_ = size;
187 PRINTD("(%" RTC_PRIuS ")", largest_size_);
188 }
189 total_written_elements_ += size;
190 }
191
192 // Read pointer to data buffer from front of list, copy |num_frames| of stored
193 // data into |destination| and delete the utilized memory allocation.
194 // Decreases the size of the FIFO by one element.
Read(void * destination,size_t num_frames)195 void Read(void* destination, size_t num_frames) override {
196 ASSERT_EQ(num_frames, frames_per_buffer_);
197 PRINTD("-");
198 rtc::CritScope lock(&lock_);
199 if (fifo_->empty()) {
200 memset(destination, 0, bytes_per_buffer_);
201 } else {
202 int16_t* memory = fifo_->front();
203 fifo_->pop_front();
204 memcpy(destination, static_cast<int16_t*>(&memory[0]), bytes_per_buffer_);
205 delete memory;
206 }
207 }
208
size() const209 size_t size() const { return fifo_->size(); }
210
largest_size() const211 size_t largest_size() const { return largest_size_; }
212
average_size() const213 size_t average_size() const {
214 return (total_written_elements_ == 0)
215 ? 0.0
216 : 0.5 + static_cast<float>(total_written_elements_) /
217 (write_count_ - kNumIgnoreFirstCallbacks);
218 }
219
220 private:
Flush()221 void Flush() {
222 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) {
223 delete *it;
224 }
225 fifo_->clear();
226 }
227
228 using AudioBufferList = std::list<int16_t*>;
229 rtc::CriticalSection lock_;
230 const size_t frames_per_buffer_;
231 const size_t bytes_per_buffer_;
232 std::unique_ptr<AudioBufferList> fifo_;
233 size_t largest_size_;
234 size_t total_written_elements_;
235 size_t write_count_;
236 };
237
238 // Inserts periodic impulses and measures the latency between the time of
239 // transmission and time of receiving the same impulse.
240 // Usage requires a special hardware called Audio Loopback Dongle.
241 // See http://source.android.com/devices/audio/loopback.html for details.
242 class LatencyMeasuringAudioStream : public AudioStreamInterface {
243 public:
LatencyMeasuringAudioStream(size_t frames_per_buffer)244 explicit LatencyMeasuringAudioStream(size_t frames_per_buffer)
245 : frames_per_buffer_(frames_per_buffer),
246 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)),
247 play_count_(0),
248 rec_count_(0),
249 pulse_time_(0) {}
250
251 // Insert periodic impulses in first two samples of |destination|.
Read(void * destination,size_t num_frames)252 void Read(void* destination, size_t num_frames) override {
253 ASSERT_EQ(num_frames, frames_per_buffer_);
254 if (play_count_ == 0) {
255 PRINT("[");
256 }
257 play_count_++;
258 memset(destination, 0, bytes_per_buffer_);
259 if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) {
260 if (pulse_time_ == 0) {
261 pulse_time_ = rtc::TimeMillis();
262 }
263 PRINT(".");
264 const int16_t impulse = std::numeric_limits<int16_t>::max();
265 int16_t* ptr16 = static_cast<int16_t*>(destination);
266 for (size_t i = 0; i < 2; ++i) {
267 ptr16[i] = impulse;
268 }
269 }
270 }
271
272 // Detect received impulses in |source|, derive time between transmission and
273 // detection and add the calculated delay to list of latencies.
Write(const void * source,size_t num_frames)274 void Write(const void* source, size_t num_frames) override {
275 ASSERT_EQ(num_frames, frames_per_buffer_);
276 rec_count_++;
277 if (pulse_time_ == 0) {
278 // Avoid detection of new impulse response until a new impulse has
279 // been transmitted (sets |pulse_time_| to value larger than zero).
280 return;
281 }
282 const int16_t* ptr16 = static_cast<const int16_t*>(source);
283 std::vector<int16_t> vec(ptr16, ptr16 + num_frames);
284 // Find max value in the audio buffer.
285 int max = *std::max_element(vec.begin(), vec.end());
286 // Find index (element position in vector) of the max element.
287 int index_of_max =
288 std::distance(vec.begin(), std::find(vec.begin(), vec.end(), max));
289 if (max > kImpulseThreshold) {
290 PRINTD("(%d,%d)", max, index_of_max);
291 int64_t now_time = rtc::TimeMillis();
292 int extra_delay = IndexToMilliseconds(static_cast<double>(index_of_max));
293 PRINTD("[%d]", static_cast<int>(now_time - pulse_time_));
294 PRINTD("[%d]", extra_delay);
295 // Total latency is the difference between transmit time and detection
296 // tome plus the extra delay within the buffer in which we detected the
297 // received impulse. It is transmitted at sample 0 but can be received
298 // at sample N where N > 0. The term |extra_delay| accounts for N and it
299 // is a value between 0 and 10ms.
300 latencies_.push_back(now_time - pulse_time_ + extra_delay);
301 pulse_time_ = 0;
302 } else {
303 PRINTD("-");
304 }
305 }
306
num_latency_values() const307 size_t num_latency_values() const { return latencies_.size(); }
308
min_latency() const309 int min_latency() const {
310 if (latencies_.empty())
311 return 0;
312 return *std::min_element(latencies_.begin(), latencies_.end());
313 }
314
max_latency() const315 int max_latency() const {
316 if (latencies_.empty())
317 return 0;
318 return *std::max_element(latencies_.begin(), latencies_.end());
319 }
320
average_latency() const321 int average_latency() const {
322 if (latencies_.empty())
323 return 0;
324 return 0.5 + static_cast<double>(
325 std::accumulate(latencies_.begin(), latencies_.end(), 0)) /
326 latencies_.size();
327 }
328
PrintResults() const329 void PrintResults() const {
330 PRINT("] ");
331 for (auto it = latencies_.begin(); it != latencies_.end(); ++it) {
332 PRINT("%d ", *it);
333 }
334 PRINT("\n");
335 PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag, min_latency(),
336 max_latency(), average_latency());
337 }
338
IndexToMilliseconds(double index) const339 int IndexToMilliseconds(double index) const {
340 return static_cast<int>(10.0 * (index / frames_per_buffer_) + 0.5);
341 }
342
343 private:
344 const size_t frames_per_buffer_;
345 const size_t bytes_per_buffer_;
346 size_t play_count_;
347 size_t rec_count_;
348 int64_t pulse_time_;
349 std::vector<int> latencies_;
350 };
351
352 // Mocks the AudioTransport object and proxies actions for the two callbacks
353 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations
354 // of AudioStreamInterface.
355 class MockAudioTransportAndroid : public test::MockAudioTransport {
356 public:
MockAudioTransportAndroid(int type)357 explicit MockAudioTransportAndroid(int type)
358 : num_callbacks_(0),
359 type_(type),
360 play_count_(0),
361 rec_count_(0),
362 audio_stream_(nullptr) {}
363
~MockAudioTransportAndroid()364 virtual ~MockAudioTransportAndroid() {}
365
366 // Set default actions of the mock object. We are delegating to fake
367 // implementations (of AudioStreamInterface) here.
HandleCallbacks(rtc::Event * test_is_done,AudioStreamInterface * audio_stream,int num_callbacks)368 void HandleCallbacks(rtc::Event* test_is_done,
369 AudioStreamInterface* audio_stream,
370 int num_callbacks) {
371 test_is_done_ = test_is_done;
372 audio_stream_ = audio_stream;
373 num_callbacks_ = num_callbacks;
374 if (play_mode()) {
375 ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _))
376 .WillByDefault(
377 Invoke(this, &MockAudioTransportAndroid::RealNeedMorePlayData));
378 }
379 if (rec_mode()) {
380 ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _))
381 .WillByDefault(Invoke(
382 this, &MockAudioTransportAndroid::RealRecordedDataIsAvailable));
383 }
384 }
385
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,const uint32_t & newMicLevel)386 int32_t RealRecordedDataIsAvailable(const void* audioSamples,
387 const size_t nSamples,
388 const size_t nBytesPerSample,
389 const size_t nChannels,
390 const uint32_t samplesPerSec,
391 const uint32_t totalDelayMS,
392 const int32_t clockDrift,
393 const uint32_t currentMicLevel,
394 const bool keyPressed,
395 const uint32_t& newMicLevel) {
396 EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks.";
397 rec_count_++;
398 // Process the recorded audio stream if an AudioStreamInterface
399 // implementation exists.
400 if (audio_stream_) {
401 audio_stream_->Write(audioSamples, nSamples);
402 }
403 if (ReceivedEnoughCallbacks()) {
404 test_is_done_->Set();
405 }
406 return 0;
407 }
408
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)409 int32_t RealNeedMorePlayData(const size_t nSamples,
410 const size_t nBytesPerSample,
411 const size_t nChannels,
412 const uint32_t samplesPerSec,
413 void* audioSamples,
414 size_t& nSamplesOut, // NOLINT
415 int64_t* elapsed_time_ms,
416 int64_t* ntp_time_ms) {
417 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks.";
418 play_count_++;
419 nSamplesOut = nSamples;
420 // Read (possibly processed) audio stream samples to be played out if an
421 // AudioStreamInterface implementation exists.
422 if (audio_stream_) {
423 audio_stream_->Read(audioSamples, nSamples);
424 }
425 if (ReceivedEnoughCallbacks()) {
426 test_is_done_->Set();
427 }
428 return 0;
429 }
430
ReceivedEnoughCallbacks()431 bool ReceivedEnoughCallbacks() {
432 bool recording_done = false;
433 if (rec_mode())
434 recording_done = rec_count_ >= num_callbacks_;
435 else
436 recording_done = true;
437
438 bool playout_done = false;
439 if (play_mode())
440 playout_done = play_count_ >= num_callbacks_;
441 else
442 playout_done = true;
443
444 return recording_done && playout_done;
445 }
446
play_mode() const447 bool play_mode() const { return type_ & kPlayout; }
rec_mode() const448 bool rec_mode() const { return type_ & kRecording; }
449
450 private:
451 rtc::Event* test_is_done_;
452 size_t num_callbacks_;
453 int type_;
454 size_t play_count_;
455 size_t rec_count_;
456 AudioStreamInterface* audio_stream_;
457 std::unique_ptr<LatencyMeasuringAudioStream> latency_audio_stream_;
458 };
459
460 // AudioDeviceTest test fixture.
461 class AudioDeviceTest : public ::testing::Test {
462 protected:
AudioDeviceTest()463 AudioDeviceTest() {
464 // One-time initialization of JVM and application context. Ensures that we
465 // can do calls between C++ and Java. Initializes both Java and OpenSL ES
466 // implementations.
467 // Creates an audio device using a default audio layer.
468 jni_ = AttachCurrentThreadIfNeeded();
469 context_ = test::GetAppContextForTest(jni_);
470 audio_device_ = CreateJavaAudioDeviceModule(jni_, context_.obj());
471 EXPECT_NE(audio_device_.get(), nullptr);
472 EXPECT_EQ(0, audio_device_->Init());
473 audio_manager_ = GetAudioManager(jni_, context_);
474 UpdateParameters();
475 }
~AudioDeviceTest()476 virtual ~AudioDeviceTest() { EXPECT_EQ(0, audio_device_->Terminate()); }
477
total_delay_ms() const478 int total_delay_ms() const { return 10; }
479
UpdateParameters()480 void UpdateParameters() {
481 int input_sample_rate = GetDefaultSampleRate(jni_, audio_manager_);
482 int output_sample_rate = GetDefaultSampleRate(jni_, audio_manager_);
483 bool stereo_playout_is_available;
484 bool stereo_record_is_available;
485 audio_device_->StereoPlayoutIsAvailable(&stereo_playout_is_available);
486 audio_device_->StereoRecordingIsAvailable(&stereo_record_is_available);
487 GetAudioParameters(jni_, context_, audio_manager_, input_sample_rate,
488 output_sample_rate, stereo_playout_is_available,
489 stereo_record_is_available, &input_parameters_,
490 &output_parameters_);
491 }
492
SetActiveAudioLayer(AudioDeviceModule::AudioLayer audio_layer)493 void SetActiveAudioLayer(AudioDeviceModule::AudioLayer audio_layer) {
494 audio_device_ = CreateAudioDevice(audio_layer);
495 EXPECT_NE(audio_device_.get(), nullptr);
496 EXPECT_EQ(0, audio_device_->Init());
497 UpdateParameters();
498 }
499
playout_sample_rate() const500 int playout_sample_rate() const { return output_parameters_.sample_rate(); }
record_sample_rate() const501 int record_sample_rate() const { return input_parameters_.sample_rate(); }
playout_channels() const502 size_t playout_channels() const { return output_parameters_.channels(); }
record_channels() const503 size_t record_channels() const { return input_parameters_.channels(); }
playout_frames_per_10ms_buffer() const504 size_t playout_frames_per_10ms_buffer() const {
505 return output_parameters_.frames_per_10ms_buffer();
506 }
record_frames_per_10ms_buffer() const507 size_t record_frames_per_10ms_buffer() const {
508 return input_parameters_.frames_per_10ms_buffer();
509 }
510
audio_device() const511 rtc::scoped_refptr<AudioDeviceModule> audio_device() const {
512 return audio_device_;
513 }
514
CreateAudioDevice(AudioDeviceModule::AudioLayer audio_layer)515 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDevice(
516 AudioDeviceModule::AudioLayer audio_layer) {
517 #if defined(WEBRTC_AUDIO_DEVICE_INCLUDE_ANDROID_AAUDIO)
518 if (audio_layer == AudioDeviceModule::kAndroidAAudioAudio) {
519 return rtc::scoped_refptr<AudioDeviceModule>(
520 CreateAAudioAudioDeviceModule(jni_, context_.obj()));
521 }
522 #endif
523 if (audio_layer == AudioDeviceModule::kAndroidJavaAudio) {
524 return rtc::scoped_refptr<AudioDeviceModule>(
525 CreateJavaAudioDeviceModule(jni_, context_.obj()));
526 } else if (audio_layer == AudioDeviceModule::kAndroidOpenSLESAudio) {
527 return rtc::scoped_refptr<AudioDeviceModule>(
528 CreateOpenSLESAudioDeviceModule(jni_, context_.obj()));
529 } else if (audio_layer ==
530 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio) {
531 return rtc::scoped_refptr<AudioDeviceModule>(
532 CreateJavaInputAndOpenSLESOutputAudioDeviceModule(jni_,
533 context_.obj()));
534 } else {
535 return nullptr;
536 }
537 }
538
539 // Returns file name relative to the resource root given a sample rate.
GetFileName(int sample_rate)540 std::string GetFileName(int sample_rate) {
541 EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100);
542 char fname[64];
543 snprintf(fname, sizeof(fname), "audio_device/audio_short%d",
544 sample_rate / 1000);
545 std::string file_name(webrtc::test::ResourcePath(fname, "pcm"));
546 EXPECT_TRUE(test::FileExists(file_name));
547 #ifdef ENABLE_PRINTF
548 PRINT("file name: %s\n", file_name.c_str());
549 const size_t bytes = test::GetFileSize(file_name);
550 PRINT("file size: %" RTC_PRIuS " [bytes]\n", bytes);
551 PRINT("file size: %" RTC_PRIuS " [samples]\n", bytes / kBytesPerSample);
552 const int seconds =
553 static_cast<int>(bytes / (sample_rate * kBytesPerSample));
554 PRINT("file size: %d [secs]\n", seconds);
555 PRINT("file size: %" RTC_PRIuS " [callbacks]\n",
556 seconds * kNumCallbacksPerSecond);
557 #endif
558 return file_name;
559 }
560
GetActiveAudioLayer() const561 AudioDeviceModule::AudioLayer GetActiveAudioLayer() const {
562 AudioDeviceModule::AudioLayer audio_layer;
563 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer));
564 return audio_layer;
565 }
566
TestDelayOnAudioLayer(const AudioDeviceModule::AudioLayer & layer_to_test)567 int TestDelayOnAudioLayer(
568 const AudioDeviceModule::AudioLayer& layer_to_test) {
569 rtc::scoped_refptr<AudioDeviceModule> audio_device;
570 audio_device = CreateAudioDevice(layer_to_test);
571 EXPECT_NE(audio_device.get(), nullptr);
572 uint16_t playout_delay;
573 EXPECT_EQ(0, audio_device->PlayoutDelay(&playout_delay));
574 return playout_delay;
575 }
576
TestActiveAudioLayer(const AudioDeviceModule::AudioLayer & layer_to_test)577 AudioDeviceModule::AudioLayer TestActiveAudioLayer(
578 const AudioDeviceModule::AudioLayer& layer_to_test) {
579 rtc::scoped_refptr<AudioDeviceModule> audio_device;
580 audio_device = CreateAudioDevice(layer_to_test);
581 EXPECT_NE(audio_device.get(), nullptr);
582 AudioDeviceModule::AudioLayer active;
583 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&active));
584 return active;
585 }
586
587 // One way to ensure that the engine object is valid is to create an
588 // SL Engine interface since it exposes creation methods of all the OpenSL ES
589 // object types and it is only supported on the engine object. This method
590 // also verifies that the engine interface supports at least one interface.
591 // Note that, the test below is not a full test of the SLEngineItf object
592 // but only a simple sanity test to check that the global engine object is OK.
ValidateSLEngine(SLObjectItf engine_object)593 void ValidateSLEngine(SLObjectItf engine_object) {
594 EXPECT_NE(nullptr, engine_object);
595 // Get the SL Engine interface which is exposed by the engine object.
596 SLEngineItf engine;
597 SLresult result =
598 (*engine_object)->GetInterface(engine_object, SL_IID_ENGINE, &engine);
599 EXPECT_EQ(result, SL_RESULT_SUCCESS) << "GetInterface() on engine failed";
600 // Ensure that the SL Engine interface exposes at least one interface.
601 SLuint32 object_id = SL_OBJECTID_ENGINE;
602 SLuint32 num_supported_interfaces = 0;
603 result = (*engine)->QueryNumSupportedInterfaces(engine, object_id,
604 &num_supported_interfaces);
605 EXPECT_EQ(result, SL_RESULT_SUCCESS)
606 << "QueryNumSupportedInterfaces() failed";
607 EXPECT_GE(num_supported_interfaces, 1u);
608 }
609
610 // Volume control is currently only supported for the Java output audio layer.
611 // For OpenSL ES, the internal stream volume is always on max level and there
612 // is no need for this test to set it to max.
AudioLayerSupportsVolumeControl() const613 bool AudioLayerSupportsVolumeControl() const {
614 return GetActiveAudioLayer() == AudioDeviceModule::kAndroidJavaAudio;
615 }
616
SetMaxPlayoutVolume()617 void SetMaxPlayoutVolume() {
618 if (!AudioLayerSupportsVolumeControl())
619 return;
620 uint32_t max_volume;
621 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume));
622 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume));
623 }
624
DisableBuiltInAECIfAvailable()625 void DisableBuiltInAECIfAvailable() {
626 if (audio_device()->BuiltInAECIsAvailable()) {
627 EXPECT_EQ(0, audio_device()->EnableBuiltInAEC(false));
628 }
629 }
630
StartPlayout()631 void StartPlayout() {
632 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
633 EXPECT_FALSE(audio_device()->Playing());
634 EXPECT_EQ(0, audio_device()->InitPlayout());
635 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
636 EXPECT_EQ(0, audio_device()->StartPlayout());
637 EXPECT_TRUE(audio_device()->Playing());
638 }
639
StopPlayout()640 void StopPlayout() {
641 EXPECT_EQ(0, audio_device()->StopPlayout());
642 EXPECT_FALSE(audio_device()->Playing());
643 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
644 }
645
StartRecording()646 void StartRecording() {
647 EXPECT_FALSE(audio_device()->RecordingIsInitialized());
648 EXPECT_FALSE(audio_device()->Recording());
649 EXPECT_EQ(0, audio_device()->InitRecording());
650 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
651 EXPECT_EQ(0, audio_device()->StartRecording());
652 EXPECT_TRUE(audio_device()->Recording());
653 }
654
StopRecording()655 void StopRecording() {
656 EXPECT_EQ(0, audio_device()->StopRecording());
657 EXPECT_FALSE(audio_device()->Recording());
658 }
659
GetMaxSpeakerVolume() const660 int GetMaxSpeakerVolume() const {
661 uint32_t max_volume(0);
662 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume));
663 return max_volume;
664 }
665
GetMinSpeakerVolume() const666 int GetMinSpeakerVolume() const {
667 uint32_t min_volume(0);
668 EXPECT_EQ(0, audio_device()->MinSpeakerVolume(&min_volume));
669 return min_volume;
670 }
671
GetSpeakerVolume() const672 int GetSpeakerVolume() const {
673 uint32_t volume(0);
674 EXPECT_EQ(0, audio_device()->SpeakerVolume(&volume));
675 return volume;
676 }
677
678 JNIEnv* jni_;
679 ScopedJavaLocalRef<jobject> context_;
680 rtc::Event test_is_done_;
681 rtc::scoped_refptr<AudioDeviceModule> audio_device_;
682 ScopedJavaLocalRef<jobject> audio_manager_;
683 AudioParameters output_parameters_;
684 AudioParameters input_parameters_;
685 };
686
TEST_F(AudioDeviceTest,ConstructDestruct)687 TEST_F(AudioDeviceTest, ConstructDestruct) {
688 // Using the test fixture to create and destruct the audio device module.
689 }
690
691 // Verify that it is possible to explicitly create the two types of supported
692 // ADMs. These two tests overrides the default selection of native audio layer
693 // by ignoring if the device supports low-latency output or not.
TEST_F(AudioDeviceTest,CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo)694 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo) {
695 AudioDeviceModule::AudioLayer expected_layer =
696 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio;
697 AudioDeviceModule::AudioLayer active_layer =
698 TestActiveAudioLayer(expected_layer);
699 EXPECT_EQ(expected_layer, active_layer);
700 }
701
TEST_F(AudioDeviceTest,CorrectAudioLayerIsUsedForJavaInBothDirections)702 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForJavaInBothDirections) {
703 AudioDeviceModule::AudioLayer expected_layer =
704 AudioDeviceModule::kAndroidJavaAudio;
705 AudioDeviceModule::AudioLayer active_layer =
706 TestActiveAudioLayer(expected_layer);
707 EXPECT_EQ(expected_layer, active_layer);
708 }
709
TEST_F(AudioDeviceTest,CorrectAudioLayerIsUsedForOpenSLInBothDirections)710 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForOpenSLInBothDirections) {
711 AudioDeviceModule::AudioLayer expected_layer =
712 AudioDeviceModule::kAndroidOpenSLESAudio;
713 AudioDeviceModule::AudioLayer active_layer =
714 TestActiveAudioLayer(expected_layer);
715 EXPECT_EQ(expected_layer, active_layer);
716 }
717
718 // TODO(bugs.webrtc.org/8914)
719 // TODO(phensman): Add test for AAudio/Java combination when this combination
720 // is supported.
721 #if !defined(WEBRTC_AUDIO_DEVICE_INCLUDE_ANDROID_AAUDIO)
722 #define MAYBE_CorrectAudioLayerIsUsedForAAudioInBothDirections \
723 DISABLED_CorrectAudioLayerIsUsedForAAudioInBothDirections
724 #else
725 #define MAYBE_CorrectAudioLayerIsUsedForAAudioInBothDirections \
726 CorrectAudioLayerIsUsedForAAudioInBothDirections
727 #endif
TEST_F(AudioDeviceTest,MAYBE_CorrectAudioLayerIsUsedForAAudioInBothDirections)728 TEST_F(AudioDeviceTest,
729 MAYBE_CorrectAudioLayerIsUsedForAAudioInBothDirections) {
730 AudioDeviceModule::AudioLayer expected_layer =
731 AudioDeviceModule::kAndroidAAudioAudio;
732 AudioDeviceModule::AudioLayer active_layer =
733 TestActiveAudioLayer(expected_layer);
734 EXPECT_EQ(expected_layer, active_layer);
735 }
736
737 // The Android ADM supports two different delay reporting modes. One for the
738 // low-latency output path (in combination with OpenSL ES), and one for the
739 // high-latency output path (Java backends in both directions). These two tests
740 // verifies that the audio device reports correct delay estimate given the
741 // selected audio layer. Note that, this delay estimate will only be utilized
742 // if the HW AEC is disabled.
743 // Delay should be 75 ms in high latency and 25 ms in low latency.
TEST_F(AudioDeviceTest,UsesCorrectDelayEstimateForHighLatencyOutputPath)744 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForHighLatencyOutputPath) {
745 EXPECT_EQ(75, TestDelayOnAudioLayer(AudioDeviceModule::kAndroidJavaAudio));
746 }
747
TEST_F(AudioDeviceTest,UsesCorrectDelayEstimateForLowLatencyOutputPath)748 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForLowLatencyOutputPath) {
749 EXPECT_EQ(25,
750 TestDelayOnAudioLayer(
751 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio));
752 }
753
TEST_F(AudioDeviceTest,InitTerminate)754 TEST_F(AudioDeviceTest, InitTerminate) {
755 // Initialization is part of the test fixture.
756 EXPECT_TRUE(audio_device()->Initialized());
757 EXPECT_EQ(0, audio_device()->Terminate());
758 EXPECT_FALSE(audio_device()->Initialized());
759 }
760
TEST_F(AudioDeviceTest,Devices)761 TEST_F(AudioDeviceTest, Devices) {
762 // Device enumeration is not supported. Verify fixed values only.
763 EXPECT_EQ(1, audio_device()->PlayoutDevices());
764 EXPECT_EQ(1, audio_device()->RecordingDevices());
765 }
766
TEST_F(AudioDeviceTest,IsAcousticEchoCancelerSupported)767 TEST_F(AudioDeviceTest, IsAcousticEchoCancelerSupported) {
768 PRINT("%sAcoustic Echo Canceler support: %s\n", kTag,
769 audio_device()->BuiltInAECIsAvailable() ? "Yes" : "No");
770 }
771
TEST_F(AudioDeviceTest,IsNoiseSuppressorSupported)772 TEST_F(AudioDeviceTest, IsNoiseSuppressorSupported) {
773 PRINT("%sNoise Suppressor support: %s\n", kTag,
774 audio_device()->BuiltInNSIsAvailable() ? "Yes" : "No");
775 }
776
777 // Verify that playout side is configured for mono by default.
TEST_F(AudioDeviceTest,UsesMonoPlayoutByDefault)778 TEST_F(AudioDeviceTest, UsesMonoPlayoutByDefault) {
779 EXPECT_EQ(1u, output_parameters_.channels());
780 }
781
782 // Verify that recording side is configured for mono by default.
TEST_F(AudioDeviceTest,UsesMonoRecordingByDefault)783 TEST_F(AudioDeviceTest, UsesMonoRecordingByDefault) {
784 EXPECT_EQ(1u, input_parameters_.channels());
785 }
786
TEST_F(AudioDeviceTest,SpeakerVolumeShouldBeAvailable)787 TEST_F(AudioDeviceTest, SpeakerVolumeShouldBeAvailable) {
788 // The OpenSL ES output audio path does not support volume control.
789 if (!AudioLayerSupportsVolumeControl())
790 return;
791 bool available;
792 EXPECT_EQ(0, audio_device()->SpeakerVolumeIsAvailable(&available));
793 EXPECT_TRUE(available);
794 }
795
TEST_F(AudioDeviceTest,MaxSpeakerVolumeIsPositive)796 TEST_F(AudioDeviceTest, MaxSpeakerVolumeIsPositive) {
797 // The OpenSL ES output audio path does not support volume control.
798 if (!AudioLayerSupportsVolumeControl())
799 return;
800 StartPlayout();
801 EXPECT_GT(GetMaxSpeakerVolume(), 0);
802 StopPlayout();
803 }
804
TEST_F(AudioDeviceTest,MinSpeakerVolumeIsZero)805 TEST_F(AudioDeviceTest, MinSpeakerVolumeIsZero) {
806 // The OpenSL ES output audio path does not support volume control.
807 if (!AudioLayerSupportsVolumeControl())
808 return;
809 EXPECT_EQ(GetMinSpeakerVolume(), 0);
810 }
811
TEST_F(AudioDeviceTest,DefaultSpeakerVolumeIsWithinMinMax)812 TEST_F(AudioDeviceTest, DefaultSpeakerVolumeIsWithinMinMax) {
813 // The OpenSL ES output audio path does not support volume control.
814 if (!AudioLayerSupportsVolumeControl())
815 return;
816 const int default_volume = GetSpeakerVolume();
817 EXPECT_GE(default_volume, GetMinSpeakerVolume());
818 EXPECT_LE(default_volume, GetMaxSpeakerVolume());
819 }
820
TEST_F(AudioDeviceTest,SetSpeakerVolumeActuallySetsVolume)821 TEST_F(AudioDeviceTest, SetSpeakerVolumeActuallySetsVolume) {
822 // The OpenSL ES output audio path does not support volume control.
823 if (!AudioLayerSupportsVolumeControl())
824 return;
825 const int default_volume = GetSpeakerVolume();
826 const int max_volume = GetMaxSpeakerVolume();
827 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume));
828 int new_volume = GetSpeakerVolume();
829 EXPECT_EQ(new_volume, max_volume);
830 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(default_volume));
831 }
832
833 // Tests that playout can be initiated, started and stopped. No audio callback
834 // is registered in this test.
TEST_F(AudioDeviceTest,StartStopPlayout)835 TEST_F(AudioDeviceTest, StartStopPlayout) {
836 StartPlayout();
837 StopPlayout();
838 StartPlayout();
839 StopPlayout();
840 }
841
842 // Tests that recording can be initiated, started and stopped. No audio callback
843 // is registered in this test.
TEST_F(AudioDeviceTest,StartStopRecording)844 TEST_F(AudioDeviceTest, StartStopRecording) {
845 StartRecording();
846 StopRecording();
847 StartRecording();
848 StopRecording();
849 }
850
851 // Verify that calling StopPlayout() will leave us in an uninitialized state
852 // which will require a new call to InitPlayout(). This test does not call
853 // StartPlayout() while being uninitialized since doing so will hit a
854 // RTC_DCHECK and death tests are not supported on Android.
TEST_F(AudioDeviceTest,StopPlayoutRequiresInitToRestart)855 TEST_F(AudioDeviceTest, StopPlayoutRequiresInitToRestart) {
856 EXPECT_EQ(0, audio_device()->InitPlayout());
857 EXPECT_EQ(0, audio_device()->StartPlayout());
858 EXPECT_EQ(0, audio_device()->StopPlayout());
859 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
860 }
861
862 // Verify that calling StopRecording() will leave us in an uninitialized state
863 // which will require a new call to InitRecording(). This test does not call
864 // StartRecording() while being uninitialized since doing so will hit a
865 // RTC_DCHECK and death tests are not supported on Android.
TEST_F(AudioDeviceTest,StopRecordingRequiresInitToRestart)866 TEST_F(AudioDeviceTest, StopRecordingRequiresInitToRestart) {
867 EXPECT_EQ(0, audio_device()->InitRecording());
868 EXPECT_EQ(0, audio_device()->StartRecording());
869 EXPECT_EQ(0, audio_device()->StopRecording());
870 EXPECT_FALSE(audio_device()->RecordingIsInitialized());
871 }
872
873 // Start playout and verify that the native audio layer starts asking for real
874 // audio samples to play out using the NeedMorePlayData callback.
TEST_F(AudioDeviceTest,StartPlayoutVerifyCallbacks)875 TEST_F(AudioDeviceTest, StartPlayoutVerifyCallbacks) {
876 MockAudioTransportAndroid mock(kPlayout);
877 mock.HandleCallbacks(&test_is_done_, nullptr, kNumCallbacks);
878 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(),
879 kBytesPerSample, playout_channels(),
880 playout_sample_rate(), NotNull(), _, _, _))
881 .Times(AtLeast(kNumCallbacks));
882 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
883 StartPlayout();
884 test_is_done_.Wait(kTestTimeOutInMilliseconds);
885 StopPlayout();
886 }
887
888 // Start recording and verify that the native audio layer starts feeding real
889 // audio samples via the RecordedDataIsAvailable callback.
TEST_F(AudioDeviceTest,StartRecordingVerifyCallbacks)890 TEST_F(AudioDeviceTest, StartRecordingVerifyCallbacks) {
891 MockAudioTransportAndroid mock(kRecording);
892 mock.HandleCallbacks(&test_is_done_, nullptr, kNumCallbacks);
893 EXPECT_CALL(
894 mock, RecordedDataIsAvailable(NotNull(), record_frames_per_10ms_buffer(),
895 kBytesPerSample, record_channels(),
896 record_sample_rate(), _, 0, 0, false, _))
897 .Times(AtLeast(kNumCallbacks));
898
899 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
900 StartRecording();
901 test_is_done_.Wait(kTestTimeOutInMilliseconds);
902 StopRecording();
903 }
904
905 // Start playout and recording (full-duplex audio) and verify that audio is
906 // active in both directions.
TEST_F(AudioDeviceTest,StartPlayoutAndRecordingVerifyCallbacks)907 TEST_F(AudioDeviceTest, StartPlayoutAndRecordingVerifyCallbacks) {
908 MockAudioTransportAndroid mock(kPlayout | kRecording);
909 mock.HandleCallbacks(&test_is_done_, nullptr, kNumCallbacks);
910 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(),
911 kBytesPerSample, playout_channels(),
912 playout_sample_rate(), NotNull(), _, _, _))
913 .Times(AtLeast(kNumCallbacks));
914 EXPECT_CALL(
915 mock, RecordedDataIsAvailable(NotNull(), record_frames_per_10ms_buffer(),
916 kBytesPerSample, record_channels(),
917 record_sample_rate(), _, 0, 0, false, _))
918 .Times(AtLeast(kNumCallbacks));
919 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
920 StartPlayout();
921 StartRecording();
922 test_is_done_.Wait(kTestTimeOutInMilliseconds);
923 StopRecording();
924 StopPlayout();
925 }
926
927 // Start playout and read audio from an external PCM file when the audio layer
928 // asks for data to play out. Real audio is played out in this test but it does
929 // not contain any explicit verification that the audio quality is perfect.
TEST_F(AudioDeviceTest,RunPlayoutWithFileAsSource)930 TEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) {
931 // TODO(henrika): extend test when mono output is supported.
932 EXPECT_EQ(1u, playout_channels());
933 NiceMock<MockAudioTransportAndroid> mock(kPlayout);
934 const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond;
935 std::string file_name = GetFileName(playout_sample_rate());
936 std::unique_ptr<FileAudioStream> file_audio_stream(
937 new FileAudioStream(num_callbacks, file_name, playout_sample_rate()));
938 mock.HandleCallbacks(&test_is_done_, file_audio_stream.get(), num_callbacks);
939 // SetMaxPlayoutVolume();
940 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
941 StartPlayout();
942 test_is_done_.Wait(kTestTimeOutInMilliseconds);
943 StopPlayout();
944 }
945
946 // It should be possible to create an OpenSL engine object if OpenSL ES based
947 // audio is requested in any direction.
TEST_F(AudioDeviceTest,TestCreateOpenSLEngine)948 TEST_F(AudioDeviceTest, TestCreateOpenSLEngine) {
949 // Verify that the global (singleton) OpenSL Engine can be acquired.
950 OpenSLEngineManager engine_manager;
951 SLObjectItf engine_object = engine_manager.GetOpenSLEngine();
952 EXPECT_NE(nullptr, engine_object);
953 // Perform a simple sanity check of the created engine object.
954 ValidateSLEngine(engine_object);
955 }
956
957 // The audio device module only suppors the same sample rate in both directions.
958 // In addition, in full-duplex low-latency mode (OpenSL ES), both input and
959 // output must use the same native buffer size to allow for usage of the fast
960 // audio track in Android.
TEST_F(AudioDeviceTest,VerifyAudioParameters)961 TEST_F(AudioDeviceTest, VerifyAudioParameters) {
962 EXPECT_EQ(output_parameters_.sample_rate(), input_parameters_.sample_rate());
963 SetActiveAudioLayer(AudioDeviceModule::kAndroidOpenSLESAudio);
964 EXPECT_EQ(output_parameters_.frames_per_buffer(),
965 input_parameters_.frames_per_buffer());
966 }
967
TEST_F(AudioDeviceTest,ShowAudioParameterInfo)968 TEST_F(AudioDeviceTest, ShowAudioParameterInfo) {
969 const bool low_latency_out = false;
970 const bool low_latency_in = false;
971 PRINT("PLAYOUT:\n");
972 PRINT("%saudio layer: %s\n", kTag,
973 low_latency_out ? "Low latency OpenSL" : "Java/JNI based AudioTrack");
974 PRINT("%ssample rate: %d Hz\n", kTag, output_parameters_.sample_rate());
975 PRINT("%schannels: %" RTC_PRIuS "\n", kTag, output_parameters_.channels());
976 PRINT("%sframes per buffer: %" RTC_PRIuS " <=> %.2f ms\n", kTag,
977 output_parameters_.frames_per_buffer(),
978 output_parameters_.GetBufferSizeInMilliseconds());
979 PRINT("RECORD: \n");
980 PRINT("%saudio layer: %s\n", kTag,
981 low_latency_in ? "Low latency OpenSL" : "Java/JNI based AudioRecord");
982 PRINT("%ssample rate: %d Hz\n", kTag, input_parameters_.sample_rate());
983 PRINT("%schannels: %" RTC_PRIuS "\n", kTag, input_parameters_.channels());
984 PRINT("%sframes per buffer: %" RTC_PRIuS " <=> %.2f ms\n", kTag,
985 input_parameters_.frames_per_buffer(),
986 input_parameters_.GetBufferSizeInMilliseconds());
987 }
988
989 // Add device-specific information to the test for logging purposes.
TEST_F(AudioDeviceTest,ShowDeviceInfo)990 TEST_F(AudioDeviceTest, ShowDeviceInfo) {
991 std::string model =
992 JavaToNativeString(jni_, Java_BuildInfo_getDeviceModel(jni_));
993 std::string brand = JavaToNativeString(jni_, Java_BuildInfo_getBrand(jni_));
994 std::string manufacturer =
995 JavaToNativeString(jni_, Java_BuildInfo_getDeviceManufacturer(jni_));
996
997 PRINT("%smodel: %s\n", kTag, model.c_str());
998 PRINT("%sbrand: %s\n", kTag, brand.c_str());
999 PRINT("%smanufacturer: %s\n", kTag, manufacturer.c_str());
1000 }
1001
1002 // Add Android build information to the test for logging purposes.
TEST_F(AudioDeviceTest,ShowBuildInfo)1003 TEST_F(AudioDeviceTest, ShowBuildInfo) {
1004 std::string release =
1005 JavaToNativeString(jni_, Java_BuildInfo_getBuildRelease(jni_));
1006 std::string build_id =
1007 JavaToNativeString(jni_, Java_BuildInfo_getAndroidBuildId(jni_));
1008 std::string build_type =
1009 JavaToNativeString(jni_, Java_BuildInfo_getBuildType(jni_));
1010 int sdk = Java_BuildInfo_getSdkVersion(jni_);
1011
1012 PRINT("%sbuild release: %s\n", kTag, release.c_str());
1013 PRINT("%sbuild id: %s\n", kTag, build_id.c_str());
1014 PRINT("%sbuild type: %s\n", kTag, build_type.c_str());
1015 PRINT("%sSDK version: %d\n", kTag, sdk);
1016 }
1017
1018 // Basic test of the AudioParameters class using default construction where
1019 // all members are set to zero.
TEST_F(AudioDeviceTest,AudioParametersWithDefaultConstruction)1020 TEST_F(AudioDeviceTest, AudioParametersWithDefaultConstruction) {
1021 AudioParameters params;
1022 EXPECT_FALSE(params.is_valid());
1023 EXPECT_EQ(0, params.sample_rate());
1024 EXPECT_EQ(0U, params.channels());
1025 EXPECT_EQ(0U, params.frames_per_buffer());
1026 EXPECT_EQ(0U, params.frames_per_10ms_buffer());
1027 EXPECT_EQ(0U, params.GetBytesPerFrame());
1028 EXPECT_EQ(0U, params.GetBytesPerBuffer());
1029 EXPECT_EQ(0U, params.GetBytesPer10msBuffer());
1030 EXPECT_EQ(0.0f, params.GetBufferSizeInMilliseconds());
1031 }
1032
1033 // Basic test of the AudioParameters class using non default construction.
TEST_F(AudioDeviceTest,AudioParametersWithNonDefaultConstruction)1034 TEST_F(AudioDeviceTest, AudioParametersWithNonDefaultConstruction) {
1035 const int kSampleRate = 48000;
1036 const size_t kChannels = 1;
1037 const size_t kFramesPerBuffer = 480;
1038 const size_t kFramesPer10msBuffer = 480;
1039 const size_t kBytesPerFrame = 2;
1040 const float kBufferSizeInMs = 10.0f;
1041 AudioParameters params(kSampleRate, kChannels, kFramesPerBuffer);
1042 EXPECT_TRUE(params.is_valid());
1043 EXPECT_EQ(kSampleRate, params.sample_rate());
1044 EXPECT_EQ(kChannels, params.channels());
1045 EXPECT_EQ(kFramesPerBuffer, params.frames_per_buffer());
1046 EXPECT_EQ(static_cast<size_t>(kSampleRate / 100),
1047 params.frames_per_10ms_buffer());
1048 EXPECT_EQ(kBytesPerFrame, params.GetBytesPerFrame());
1049 EXPECT_EQ(kBytesPerFrame * kFramesPerBuffer, params.GetBytesPerBuffer());
1050 EXPECT_EQ(kBytesPerFrame * kFramesPer10msBuffer,
1051 params.GetBytesPer10msBuffer());
1052 EXPECT_EQ(kBufferSizeInMs, params.GetBufferSizeInMilliseconds());
1053 }
1054
1055 // Start playout and recording and store recorded data in an intermediate FIFO
1056 // buffer from which the playout side then reads its samples in the same order
1057 // as they were stored. Under ideal circumstances, a callback sequence would
1058 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-'
1059 // means 'packet played'. Under such conditions, the FIFO would only contain
1060 // one packet on average. However, under more realistic conditions, the size
1061 // of the FIFO will vary more due to an unbalance between the two sides.
1062 // This test tries to verify that the device maintains a balanced callback-
1063 // sequence by running in loopback for kFullDuplexTimeInSec seconds while
1064 // measuring the size (max and average) of the FIFO. The size of the FIFO is
1065 // increased by the recording side and decreased by the playout side.
1066 // TODO(henrika): tune the final test parameters after running tests on several
1067 // different devices.
1068 // Disabling this test on bots since it is difficult to come up with a robust
1069 // test condition that all worked as intended. The main issue is that, when
1070 // swarming is used, an initial latency can be built up when the both sides
1071 // starts at different times. Hence, the test can fail even if audio works
1072 // as intended. Keeping the test so it can be enabled manually.
1073 // http://bugs.webrtc.org/7744
TEST_F(AudioDeviceTest,DISABLED_RunPlayoutAndRecordingInFullDuplex)1074 TEST_F(AudioDeviceTest, DISABLED_RunPlayoutAndRecordingInFullDuplex) {
1075 EXPECT_EQ(record_channels(), playout_channels());
1076 EXPECT_EQ(record_sample_rate(), playout_sample_rate());
1077 NiceMock<MockAudioTransportAndroid> mock(kPlayout | kRecording);
1078 std::unique_ptr<FifoAudioStream> fifo_audio_stream(
1079 new FifoAudioStream(playout_frames_per_10ms_buffer()));
1080 mock.HandleCallbacks(&test_is_done_, fifo_audio_stream.get(),
1081 kFullDuplexTimeInSec * kNumCallbacksPerSecond);
1082 SetMaxPlayoutVolume();
1083 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1084 StartRecording();
1085 StartPlayout();
1086 test_is_done_.Wait(
1087 std::max(kTestTimeOutInMilliseconds, 1000 * kFullDuplexTimeInSec));
1088 StopPlayout();
1089 StopRecording();
1090
1091 // These thresholds are set rather high to accomodate differences in hardware
1092 // in several devices, so this test can be used in swarming.
1093 // See http://bugs.webrtc.org/6464
1094 EXPECT_LE(fifo_audio_stream->average_size(), 60u);
1095 EXPECT_LE(fifo_audio_stream->largest_size(), 70u);
1096 }
1097
1098 // Measures loopback latency and reports the min, max and average values for
1099 // a full duplex audio session.
1100 // The latency is measured like so:
1101 // - Insert impulses periodically on the output side.
1102 // - Detect the impulses on the input side.
1103 // - Measure the time difference between the transmit time and receive time.
1104 // - Store time differences in a vector and calculate min, max and average.
1105 // This test requires a special hardware called Audio Loopback Dongle.
1106 // See http://source.android.com/devices/audio/loopback.html for details.
TEST_F(AudioDeviceTest,DISABLED_MeasureLoopbackLatency)1107 TEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) {
1108 EXPECT_EQ(record_channels(), playout_channels());
1109 EXPECT_EQ(record_sample_rate(), playout_sample_rate());
1110 NiceMock<MockAudioTransportAndroid> mock(kPlayout | kRecording);
1111 std::unique_ptr<LatencyMeasuringAudioStream> latency_audio_stream(
1112 new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer()));
1113 mock.HandleCallbacks(&test_is_done_, latency_audio_stream.get(),
1114 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond);
1115 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1116 SetMaxPlayoutVolume();
1117 DisableBuiltInAECIfAvailable();
1118 StartRecording();
1119 StartPlayout();
1120 test_is_done_.Wait(
1121 std::max(kTestTimeOutInMilliseconds, 1000 * kMeasureLatencyTimeInSec));
1122 StopPlayout();
1123 StopRecording();
1124 // Verify that the correct number of transmitted impulses are detected.
1125 EXPECT_EQ(latency_audio_stream->num_latency_values(),
1126 static_cast<size_t>(
1127 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1));
1128 latency_audio_stream->PrintResults();
1129 }
1130
TEST(JavaAudioDeviceTest,TestRunningTwoAdmsSimultaneously)1131 TEST(JavaAudioDeviceTest, TestRunningTwoAdmsSimultaneously) {
1132 JNIEnv* jni = AttachCurrentThreadIfNeeded();
1133 ScopedJavaLocalRef<jobject> context = test::GetAppContextForTest(jni);
1134
1135 // Create and start the first ADM.
1136 rtc::scoped_refptr<AudioDeviceModule> adm_1 =
1137 CreateJavaAudioDeviceModule(jni, context.obj());
1138 EXPECT_EQ(0, adm_1->Init());
1139 EXPECT_EQ(0, adm_1->InitRecording());
1140 EXPECT_EQ(0, adm_1->StartRecording());
1141
1142 // Create and start a second ADM. Expect this to fail due to the microphone
1143 // already being in use.
1144 rtc::scoped_refptr<AudioDeviceModule> adm_2 =
1145 CreateJavaAudioDeviceModule(jni, context.obj());
1146 int32_t err = adm_2->Init();
1147 err |= adm_2->InitRecording();
1148 err |= adm_2->StartRecording();
1149 EXPECT_NE(0, err);
1150
1151 // Stop and terminate second adm.
1152 adm_2->StopRecording();
1153 adm_2->Terminate();
1154
1155 // Stop first ADM.
1156 EXPECT_EQ(0, adm_1->StopRecording());
1157 EXPECT_EQ(0, adm_1->Terminate());
1158 }
1159
1160 } // namespace jni
1161
1162 } // namespace webrtc
1163