• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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