1474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org/* 2474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org * 4474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org * Use of this source code is governed by a BSD-style license 5474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org * that can be found in the LICENSE file in the root of the source 6474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org * tree. An additional intellectual property rights grant can be found 7474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org * in the file PATENTS. All contributing project authors may 8474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org */ 10474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 11ee369e4277e48624bb557f0264644ed19a40dd67henrika#include <algorithm> 12ee369e4277e48624bb557f0264644ed19a40dd67henrika#include <limits> 1380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org#include <list> 1480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org#include <numeric> 15ee369e4277e48624bb557f0264644ed19a40dd67henrika#include <string> 16ee369e4277e48624bb557f0264644ed19a40dd67henrika#include <vector> 1780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 18474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#include "testing/gmock/include/gmock/gmock.h" 19474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#include "testing/gtest/include/gtest/gtest.h" 20b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika#include "webrtc/base/arraysize.h" 2180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org#include "webrtc/base/criticalsection.h" 22dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting#include "webrtc/base/format_macros.h" 23474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#include "webrtc/base/scoped_ptr.h" 2426b08605e2b99136fcc1cab0800234f469d6e236Peter Boström#include "webrtc/base/scoped_ref_ptr.h" 25b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika#include "webrtc/modules/audio_device/android/audio_common.h" 26b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika#include "webrtc/modules/audio_device/android/audio_manager.h" 27523183b4aa2118b483967fccfdbe5b848c3eb18dhenrika#include "webrtc/modules/audio_device/android/build_info.h" 28474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#include "webrtc/modules/audio_device/android/ensure_initialized.h" 29474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#include "webrtc/modules/audio_device/audio_device_impl.h" 30474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#include "webrtc/modules/audio_device/include/audio_device.h" 3198f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/clock.h" 3298f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/event_wrapper.h" 3398f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/sleep.h" 34474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#include "webrtc/test/testsupport/fileutils.h" 35474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 36474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing std::cout; 37474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing std::endl; 38474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing ::testing::_; 39474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing ::testing::AtLeast; 40474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing ::testing::Gt; 41474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing ::testing::Invoke; 42474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing ::testing::NiceMock; 43474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing ::testing::NotNull; 44474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing ::testing::Return; 45474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgusing ::testing::TestWithParam; 46474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 4780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// #define ENABLE_DEBUG_PRINTF 4880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org#ifdef ENABLE_DEBUG_PRINTF 4980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org#define PRINTD(...) fprintf(stderr, __VA_ARGS__); 50474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#else 5180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org#define PRINTD(...) ((void)0) 52474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#endif 5380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org#define PRINT(...) fprintf(stderr, __VA_ARGS__); 54474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 55474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgnamespace webrtc { 56474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 57474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// Number of callbacks (input or output) the tests waits for before we set 58474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// an event indicating that the test was OK. 59dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingstatic const size_t kNumCallbacks = 10; 60474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// Max amount of time we wait for an event to be set while counting callbacks. 61474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgstatic const int kTestTimeOutInMilliseconds = 10 * 1000; 62474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// Average number of audio callbacks per second assuming 10ms packet size. 63dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingstatic const size_t kNumCallbacksPerSecond = 100; 64474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// Play out a test file during this time (unit is in seconds). 6580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgstatic const int kFilePlayTimeInSec = 5; 66dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingstatic const size_t kBitsPerSample = 16; 67dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingstatic const size_t kBytesPerSample = kBitsPerSample / 8; 6880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Run the full-duplex test during this time (unit is in seconds). 6980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Note that first |kNumIgnoreFirstCallbacks| are ignored. 708324b525dce2c502bbd24b3946bbae207645cde9henrikastatic const int kFullDuplexTimeInSec = 5; 7180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Wait for the callback sequence to stabilize by ignoring this amount of the 7280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// initial callbacks (avoids initial FIFO access). 7380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Only used in the RunPlayoutAndRecordingInFullDuplex test. 74dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingstatic const size_t kNumIgnoreFirstCallbacks = 50; 7580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Sets the number of impulses per second in the latency test. 7680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgstatic const int kImpulseFrequencyInHz = 1; 7780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Length of round-trip latency measurements. Number of transmitted impulses 7880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// is kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1. 7980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgstatic const int kMeasureLatencyTimeInSec = 11; 8080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Utilized in round-trip latency measurements to avoid capturing noise samples. 81b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikastatic const int kImpulseThreshold = 1000; 8280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgstatic const char kTag[] = "[..........] "; 83474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 84474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.orgenum TransportType { 85474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org kPlayout = 0x1, 86474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org kRecording = 0x2, 87474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org}; 88474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 8980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Interface for processing the audio stream. Real implementations can e.g. 9080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// run audio in loopback, read audio from a file or perform latency 9180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// measurements. 9280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgclass AudioStreamInterface { 93474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org public: 94dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting virtual void Write(const void* source, size_t num_frames) = 0; 95dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting virtual void Read(void* destination, size_t num_frames) = 0; 9680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org protected: 9780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org virtual ~AudioStreamInterface() {} 9880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org}; 9980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 10080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Reads audio samples from a PCM file where the file is stored in memory at 10180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// construction. 10280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgclass FileAudioStream : public AudioStreamInterface { 10380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org public: 10480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org FileAudioStream( 105dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t num_callbacks, const std::string& file_name, int sample_rate) 10680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org : file_size_in_bytes_(0), 10780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org sample_rate_(sample_rate), 10880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org file_pos_(0) { 109474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org file_size_in_bytes_ = test::GetFileSize(file_name); 110474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org sample_rate_ = sample_rate; 11180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org EXPECT_GE(file_size_in_callbacks(), num_callbacks) 11274d4792af574a90c4a13b3e57195883e2a546cbehenrika@webrtc.org << "Size of test file is not large enough to last during the test."; 113dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t num_16bit_samples = 114474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org test::GetFileSize(file_name) / kBytesPerSample; 115474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org file_.reset(new int16_t[num_16bit_samples]); 116474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org FILE* audio_file = fopen(file_name.c_str(), "rb"); 117474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_NE(audio_file, nullptr); 118dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t num_samples_read = fread( 119474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org file_.get(), sizeof(int16_t), num_16bit_samples, audio_file); 120474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(num_samples_read, num_16bit_samples); 121474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org fclose(audio_file); 122474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 123474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 12480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // AudioStreamInterface::Write() is not implemented. 125dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting void Write(const void* source, size_t num_frames) override {} 12680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 12780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Read samples from file stored in memory (at construction) and copy 12880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // |num_frames| (<=> 10ms) to the |destination| byte buffer. 129dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting void Read(void* destination, size_t num_frames) override { 13080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org memcpy(destination, 13180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org static_cast<int16_t*> (&file_[file_pos_]), 13280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org num_frames * sizeof(int16_t)); 13380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org file_pos_ += num_frames; 13480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 13580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 13680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int file_size_in_seconds() const { 137dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting return static_cast<int>( 138dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting file_size_in_bytes_ / (kBytesPerSample * sample_rate_)); 13980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 140dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t file_size_in_callbacks() const { 14180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return file_size_in_seconds() * kNumCallbacksPerSecond; 14280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 14380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 14480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org private: 145dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t file_size_in_bytes_; 14680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int sample_rate_; 14780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::scoped_ptr<int16_t[]> file_; 148dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t file_pos_; 14980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org}; 15080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 15180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Simple first in first out (FIFO) class that wraps a list of 16-bit audio 15280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// buffers of fixed size and allows Write and Read operations. The idea is to 15380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// store recorded audio buffers (using Write) and then read (using Read) these 15480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// stored buffers with as short delay as possible when the audio layer needs 15580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// data to play out. The number of buffers in the FIFO will stabilize under 15680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// normal conditions since there will be a balance between Write and Read calls. 15780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// The container is a std::list container and access is protected with a lock 15880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// since both sides (playout and recording) are driven by its own thread. 15980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgclass FifoAudioStream : public AudioStreamInterface { 16080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org public: 161dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting explicit FifoAudioStream(size_t frames_per_buffer) 16280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org : frames_per_buffer_(frames_per_buffer), 16380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)), 16480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org fifo_(new AudioBufferList), 16580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org largest_size_(0), 16680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org total_written_elements_(0), 16780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org write_count_(0) { 16880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org EXPECT_NE(fifo_.get(), nullptr); 16980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 17080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 17180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org ~FifoAudioStream() { 17280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org Flush(); 17380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 17480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 17580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Allocate new memory, copy |num_frames| samples from |source| into memory 17680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // and add pointer to the memory location to end of the list. 17780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Increases the size of the FIFO by one element. 178dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting void Write(const void* source, size_t num_frames) override { 17980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org ASSERT_EQ(num_frames, frames_per_buffer_); 18080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINTD("+"); 18180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (write_count_++ < kNumIgnoreFirstCallbacks) { 18280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return; 18380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 18480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int16_t* memory = new int16_t[frames_per_buffer_]; 18580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org memcpy(static_cast<int16_t*> (&memory[0]), 18680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org source, 18780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org bytes_per_buffer_); 18880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::CritScope lock(&lock_); 18980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org fifo_->push_back(memory); 190dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t size = fifo_->size(); 19180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (size > largest_size_) { 19280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org largest_size_ = size; 193dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting PRINTD("(%" PRIuS ")", largest_size_); 19480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 19580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org total_written_elements_ += size; 19680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 19780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 19880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Read pointer to data buffer from front of list, copy |num_frames| of stored 19980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // data into |destination| and delete the utilized memory allocation. 20080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Decreases the size of the FIFO by one element. 201dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting void Read(void* destination, size_t num_frames) override { 20280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org ASSERT_EQ(num_frames, frames_per_buffer_); 20380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINTD("-"); 20480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::CritScope lock(&lock_); 20580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (fifo_->empty()) { 20680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org memset(destination, 0, bytes_per_buffer_); 20780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } else { 20880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int16_t* memory = fifo_->front(); 20980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org fifo_->pop_front(); 21080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org memcpy(destination, 21180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org static_cast<int16_t*> (&memory[0]), 21280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org bytes_per_buffer_); 21380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org delete memory; 21480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 21580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 21680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 217dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t size() const { 21880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return fifo_->size(); 21980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 22080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 221dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t largest_size() const { 22280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return largest_size_; 22380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 22480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 225dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t average_size() const { 22680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return (total_written_elements_ == 0) ? 0.0 : 0.5 + static_cast<float> ( 22780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org total_written_elements_) / (write_count_ - kNumIgnoreFirstCallbacks); 22880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 22980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 23080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org private: 23180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org void Flush() { 23280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org for (auto it = fifo_->begin(); it != fifo_->end(); ++it) { 23380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org delete *it; 23480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 23580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org fifo_->clear(); 23680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 23780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 23880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org using AudioBufferList = std::list<int16_t*>; 23980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::CriticalSection lock_; 240dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t frames_per_buffer_; 241dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t bytes_per_buffer_; 24280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::scoped_ptr<AudioBufferList> fifo_; 243dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t largest_size_; 244dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t total_written_elements_; 245dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t write_count_; 24680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org}; 24780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 24880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Inserts periodic impulses and measures the latency between the time of 24980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// transmission and time of receiving the same impulse. 25080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Usage requires a special hardware called Audio Loopback Dongle. 25180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// See http://source.android.com/devices/audio/loopback.html for details. 25280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgclass LatencyMeasuringAudioStream : public AudioStreamInterface { 25380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org public: 254dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting explicit LatencyMeasuringAudioStream(size_t frames_per_buffer) 25580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org : clock_(Clock::GetRealTimeClock()), 25680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org frames_per_buffer_(frames_per_buffer), 25780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)), 25880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org play_count_(0), 25980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rec_count_(0), 26080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org pulse_time_(0) { 26180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 26280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 26380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Insert periodic impulses in first two samples of |destination|. 264dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting void Read(void* destination, size_t num_frames) override { 26580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org ASSERT_EQ(num_frames, frames_per_buffer_); 26680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (play_count_ == 0) { 26780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINT("["); 26880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 26980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org play_count_++; 27080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org memset(destination, 0, bytes_per_buffer_); 27180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) { 27280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (pulse_time_ == 0) { 27380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org pulse_time_ = clock_->TimeInMilliseconds(); 27480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 27580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINT("."); 27680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org const int16_t impulse = std::numeric_limits<int16_t>::max(); 27780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int16_t* ptr16 = static_cast<int16_t*> (destination); 278dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting for (size_t i = 0; i < 2; ++i) { 279dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting ptr16[i] = impulse; 28080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 28180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 28280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 28380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 28480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Detect received impulses in |source|, derive time between transmission and 28580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // detection and add the calculated delay to list of latencies. 286dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting void Write(const void* source, size_t num_frames) override { 28780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org ASSERT_EQ(num_frames, frames_per_buffer_); 28880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rec_count_++; 28980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (pulse_time_ == 0) { 29080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Avoid detection of new impulse response until a new impulse has 29180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // been transmitted (sets |pulse_time_| to value larger than zero). 29280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return; 29380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 29480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org const int16_t* ptr16 = static_cast<const int16_t*> (source); 29580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org std::vector<int16_t> vec(ptr16, ptr16 + num_frames); 29680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Find max value in the audio buffer. 29780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int max = *std::max_element(vec.begin(), vec.end()); 29880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Find index (element position in vector) of the max element. 29980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int index_of_max = std::distance(vec.begin(), 30080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org std::find(vec.begin(), vec.end(), 30180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org max)); 30280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (max > kImpulseThreshold) { 30380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINTD("(%d,%d)", max, index_of_max); 30480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int64_t now_time = clock_->TimeInMilliseconds(); 30580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int extra_delay = IndexToMilliseconds(static_cast<double> (index_of_max)); 30680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINTD("[%d]", static_cast<int> (now_time - pulse_time_)); 30780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINTD("[%d]", extra_delay); 30880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Total latency is the difference between transmit time and detection 30980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // tome plus the extra delay within the buffer in which we detected the 31080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // received impulse. It is transmitted at sample 0 but can be received 31180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // at sample N where N > 0. The term |extra_delay| accounts for N and it 31280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // is a value between 0 and 10ms. 31380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org latencies_.push_back(now_time - pulse_time_ + extra_delay); 31480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org pulse_time_ = 0; 31580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } else { 31680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINTD("-"); 31780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 31880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 31980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 320dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t num_latency_values() const { 32180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return latencies_.size(); 32280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 32380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 32480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int min_latency() const { 32580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (latencies_.empty()) 32680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return 0; 32780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return *std::min_element(latencies_.begin(), latencies_.end()); 32880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 32980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 33080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int max_latency() const { 33180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (latencies_.empty()) 33280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return 0; 33380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return *std::max_element(latencies_.begin(), latencies_.end()); 33480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 33580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 33680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int average_latency() const { 33780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (latencies_.empty()) 33880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return 0; 33980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org return 0.5 + static_cast<double> ( 34080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org std::accumulate(latencies_.begin(), latencies_.end(), 0)) / 34180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org latencies_.size(); 34280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 34380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 34480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org void PrintResults() const { 34580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINT("] "); 34680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org for (auto it = latencies_.begin(); it != latencies_.end(); ++it) { 34780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINT("%d ", *it); 34880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 34980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINT("\n"); 35080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag, 35180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org min_latency(), max_latency(), average_latency()); 35280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 35380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 35480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int IndexToMilliseconds(double index) const { 355b297c5a01f88219da26cffe433804963d1b70f0fpkasting return static_cast<int>(10.0 * (index / frames_per_buffer_) + 0.5); 35680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 35780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 35880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org private: 35980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org Clock* clock_; 360dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t frames_per_buffer_; 361dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t bytes_per_buffer_; 362dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t play_count_; 363dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t rec_count_; 36480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int64_t pulse_time_; 36580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org std::vector<int> latencies_; 36680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org}; 36780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 36880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Mocks the AudioTransport object and proxies actions for the two callbacks 36980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// (RecordedDataIsAvailable and NeedMorePlayData) to different implementations 37080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// of AudioStreamInterface. 37180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.orgclass MockAudioTransport : public AudioTransport { 37280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org public: 37380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org explicit MockAudioTransport(int type) 37480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org : num_callbacks_(0), 37580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org type_(type), 37680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org play_count_(0), 37780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rec_count_(0), 37880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org audio_stream_(nullptr) {} 37980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 38080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org virtual ~MockAudioTransport() {} 38180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 382474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org MOCK_METHOD10(RecordedDataIsAvailable, 383474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org int32_t(const void* audioSamples, 384dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t nSamples, 385dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t nBytesPerSample, 3866955870806624479723addfae6dcf5d13968796cPeter Kasting const size_t nChannels, 387474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const uint32_t samplesPerSec, 388474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const uint32_t totalDelayMS, 389474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const int32_t clockDrift, 390474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const uint32_t currentMicLevel, 391474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const bool keyPressed, 392474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org uint32_t& newMicLevel)); 393474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org MOCK_METHOD8(NeedMorePlayData, 394dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting int32_t(const size_t nSamples, 395dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t nBytesPerSample, 3966955870806624479723addfae6dcf5d13968796cPeter Kasting const size_t nChannels, 397474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const uint32_t samplesPerSec, 398474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org void* audioSamples, 399dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t& nSamplesOut, 400474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org int64_t* elapsed_time_ms, 401474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org int64_t* ntp_time_ms)); 402474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 40380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Set default actions of the mock object. We are delegating to fake 40480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // implementations (of AudioStreamInterface) here. 40580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org void HandleCallbacks(EventWrapper* test_is_done, 40680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org AudioStreamInterface* audio_stream, 40780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org int num_callbacks) { 408474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org test_is_done_ = test_is_done; 40980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org audio_stream_ = audio_stream; 410474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org num_callbacks_ = num_callbacks; 411474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org if (play_mode()) { 412474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _)) 413474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org .WillByDefault( 414474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org Invoke(this, &MockAudioTransport::RealNeedMorePlayData)); 415474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 416474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org if (rec_mode()) { 417474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _)) 418474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org .WillByDefault( 419474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org Invoke(this, &MockAudioTransport::RealRecordedDataIsAvailable)); 420474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 421474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 422474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 423474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org int32_t RealRecordedDataIsAvailable(const void* audioSamples, 424dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t nSamples, 425dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t nBytesPerSample, 4266955870806624479723addfae6dcf5d13968796cPeter Kasting const size_t nChannels, 427474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const uint32_t samplesPerSec, 428474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const uint32_t totalDelayMS, 429474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const int32_t clockDrift, 430474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const uint32_t currentMicLevel, 431474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const bool keyPressed, 432474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org uint32_t& newMicLevel) { 43374d4792af574a90c4a13b3e57195883e2a546cbehenrika@webrtc.org EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks."; 434474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org rec_count_++; 43580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Process the recorded audio stream if an AudioStreamInterface 43680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // implementation exists. 43780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (audio_stream_) { 43880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org audio_stream_->Write(audioSamples, nSamples); 43980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 44080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (ReceivedEnoughCallbacks()) { 441474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org test_is_done_->Set(); 44280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 443474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org return 0; 444474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 445474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 446dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting int32_t RealNeedMorePlayData(const size_t nSamples, 447dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t nBytesPerSample, 4486955870806624479723addfae6dcf5d13968796cPeter Kasting const size_t nChannels, 449474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org const uint32_t samplesPerSec, 450474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org void* audioSamples, 451dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t& nSamplesOut, 452474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org int64_t* elapsed_time_ms, 453474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org int64_t* ntp_time_ms) { 45474d4792af574a90c4a13b3e57195883e2a546cbehenrika@webrtc.org EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks."; 45580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org play_count_++; 456474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org nSamplesOut = nSamples; 45780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Read (possibly processed) audio stream samples to be played out if an 45880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // AudioStreamInterface implementation exists. 45980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (audio_stream_) { 46080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org audio_stream_->Read(audioSamples, nSamples); 461474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 46280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org if (ReceivedEnoughCallbacks()) { 463474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org test_is_done_->Set(); 46480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org } 465474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org return 0; 466474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 467474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 468474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org bool ReceivedEnoughCallbacks() { 469474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org bool recording_done = false; 470474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org if (rec_mode()) 471474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org recording_done = rec_count_ >= num_callbacks_; 472474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org else 473474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org recording_done = true; 474474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 475474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org bool playout_done = false; 476474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org if (play_mode()) 477474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org playout_done = play_count_ >= num_callbacks_; 478474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org else 479474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org playout_done = true; 480474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 481474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org return recording_done && playout_done; 482474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 483474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 484474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org bool play_mode() const { return type_ & kPlayout; } 485474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org bool rec_mode() const { return type_ & kRecording; } 486474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 487474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org private: 488474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EventWrapper* test_is_done_; 489dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t num_callbacks_; 490474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org int type_; 491dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t play_count_; 492dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t rec_count_; 49380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org AudioStreamInterface* audio_stream_; 49480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream_; 495474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org}; 496474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 497b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// AudioDeviceTest test fixture. 498b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaclass AudioDeviceTest : public ::testing::Test { 499474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org protected: 500474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org AudioDeviceTest() 501474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org : test_is_done_(EventWrapper::Create()) { 502474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org // One-time initialization of JVM and application context. Ensures that we 503474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org // can do calls between C++ and Java. Initializes both Java and OpenSL ES 504474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org // implementations. 505474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org webrtc::audiodevicemodule::EnsureInitialized(); 506b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // Creates an audio device using a default audio layer. 507b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika audio_device_ = CreateAudioDevice(AudioDeviceModule::kPlatformDefaultAudio); 508474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_NE(audio_device_.get(), nullptr); 509474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device_->Init()); 510b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika playout_parameters_ = audio_manager()->GetPlayoutAudioParameters(); 511b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika record_parameters_ = audio_manager()->GetRecordAudioParameters(); 512523183b4aa2118b483967fccfdbe5b848c3eb18dhenrika build_info_.reset(new BuildInfo()); 513474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 514474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org virtual ~AudioDeviceTest() { 515474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device_->Terminate()); 516474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 517474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 518474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org int playout_sample_rate() const { 519b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return playout_parameters_.sample_rate(); 520474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 521b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika int record_sample_rate() const { 522b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return record_parameters_.sample_rate(); 523474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 5246955870806624479723addfae6dcf5d13968796cPeter Kasting size_t playout_channels() const { 525b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return playout_parameters_.channels(); 526474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 5276955870806624479723addfae6dcf5d13968796cPeter Kasting size_t record_channels() const { 528b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return record_parameters_.channels(); 529474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 530dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t playout_frames_per_10ms_buffer() const { 531b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return playout_parameters_.frames_per_10ms_buffer(); 532474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 533dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t record_frames_per_10ms_buffer() const { 534b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return record_parameters_.frames_per_10ms_buffer(); 535b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 536b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 537b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika int total_delay_ms() const { 538b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return audio_manager()->GetDelayEstimateInMilliseconds(); 539474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 540474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 54126b08605e2b99136fcc1cab0800234f469d6e236Peter Boström rtc::scoped_refptr<AudioDeviceModule> audio_device() const { 542474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org return audio_device_; 543474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 544474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 545b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModuleImpl* audio_device_impl() const { 546b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return static_cast<AudioDeviceModuleImpl*>(audio_device_.get()); 547b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 548b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 549b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioManager* audio_manager() const { 550b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return audio_device_impl()->GetAndroidAudioManagerForTest(); 551474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 552474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 553b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioManager* GetAudioManager(AudioDeviceModule* adm) const { 554b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return static_cast<AudioDeviceModuleImpl*>(adm)-> 555b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika GetAndroidAudioManagerForTest(); 556b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 557b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 558b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceBuffer* audio_device_buffer() const { 559b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return audio_device_impl()->GetAudioDeviceBuffer(); 560b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 561b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 56226b08605e2b99136fcc1cab0800234f469d6e236Peter Boström rtc::scoped_refptr<AudioDeviceModule> CreateAudioDevice( 563b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer audio_layer) { 56426b08605e2b99136fcc1cab0800234f469d6e236Peter Boström rtc::scoped_refptr<AudioDeviceModule> module( 565b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModuleImpl::Create(0, audio_layer)); 566b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return module; 567474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 568474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 56980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Returns file name relative to the resource root given a sample rate. 570474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org std::string GetFileName(int sample_rate) { 571474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100); 572474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org char fname[64]; 573474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org snprintf(fname, 574474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org sizeof(fname), 575474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org "audio_device/audio_short%d", 576474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org sample_rate / 1000); 577474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org std::string file_name(webrtc::test::ResourcePath(fname, "pcm")); 578474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_TRUE(test::FileExists(file_name)); 579474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#ifdef ENABLE_PRINTF 580474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org PRINT("file name: %s\n", file_name.c_str()); 581dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t bytes = test::GetFileSize(file_name); 582dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting PRINT("file size: %" PRIuS " [bytes]\n", bytes); 583dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting PRINT("file size: %" PRIuS " [samples]\n", bytes / kBytesPerSample); 584dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const int seconds = 585dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting static_cast<int>(bytes / (sample_rate * kBytesPerSample)); 586474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org PRINT("file size: %d [secs]\n", seconds); 587dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting PRINT("file size: %" PRIuS " [callbacks]\n", 588dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting seconds * kNumCallbacksPerSecond); 589474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org#endif 590474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org return file_name; 591474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 592474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 593b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer GetActiveAudioLayer() const { 594b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer audio_layer; 595b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer)); 596b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return audio_layer; 597b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 598b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 599b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika int TestDelayOnAudioLayer( 600b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika const AudioDeviceModule::AudioLayer& layer_to_test) { 60126b08605e2b99136fcc1cab0800234f469d6e236Peter Boström rtc::scoped_refptr<AudioDeviceModule> audio_device; 602b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika audio_device = CreateAudioDevice(layer_to_test); 603b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_NE(audio_device.get(), nullptr); 604b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioManager* audio_manager = GetAudioManager(audio_device.get()); 605b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_NE(audio_manager, nullptr); 606b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return audio_manager->GetDelayEstimateInMilliseconds(); 607b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 608b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 609b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer TestActiveAudioLayer( 610b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika const AudioDeviceModule::AudioLayer& layer_to_test) { 61126b08605e2b99136fcc1cab0800234f469d6e236Peter Boström rtc::scoped_refptr<AudioDeviceModule> audio_device; 612b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika audio_device = CreateAudioDevice(layer_to_test); 613b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_NE(audio_device.get(), nullptr); 614b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer active; 615b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(0, audio_device->ActiveAudioLayer(&active)); 616b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return active; 617b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 618b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 619523183b4aa2118b483967fccfdbe5b848c3eb18dhenrika bool DisableTestForThisDevice(const std::string& model) { 620523183b4aa2118b483967fccfdbe5b848c3eb18dhenrika return (build_info_->GetDeviceModel() == model); 621523183b4aa2118b483967fccfdbe5b848c3eb18dhenrika } 622523183b4aa2118b483967fccfdbe5b848c3eb18dhenrika 623b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // Volume control is currently only supported for the Java output audio layer. 624b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // For OpenSL ES, the internal stream volume is always on max level and there 625b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // is no need for this test to set it to max. 626b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika bool AudioLayerSupportsVolumeControl() const { 627b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return GetActiveAudioLayer() == AudioDeviceModule::kAndroidJavaAudio; 628b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 629b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 6308324b525dce2c502bbd24b3946bbae207645cde9henrika void SetMaxPlayoutVolume() { 631b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika if (!AudioLayerSupportsVolumeControl()) 632b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return; 6338324b525dce2c502bbd24b3946bbae207645cde9henrika uint32_t max_volume; 6348324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume)); 6358324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume)); 6368324b525dce2c502bbd24b3946bbae207645cde9henrika } 6378324b525dce2c502bbd24b3946bbae207645cde9henrika 638b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika void DisableBuiltInAECIfAvailable() { 639b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika if (audio_device()->BuiltInAECIsAvailable()) { 640b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(0, audio_device()->EnableBuiltInAEC(false)); 641b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 642b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika } 643b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 644474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org void StartPlayout() { 645474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 646474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_FALSE(audio_device()->Playing()); 647474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->InitPlayout()); 648474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_TRUE(audio_device()->PlayoutIsInitialized()); 649474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->StartPlayout()); 650474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_TRUE(audio_device()->Playing()); 651474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 652474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 653474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org void StopPlayout() { 654474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->StopPlayout()); 655474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_FALSE(audio_device()->Playing()); 656b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 657474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 658474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 659474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org void StartRecording() { 660474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_FALSE(audio_device()->RecordingIsInitialized()); 661474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_FALSE(audio_device()->Recording()); 662474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->InitRecording()); 663474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_TRUE(audio_device()->RecordingIsInitialized()); 664474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->StartRecording()); 665474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_TRUE(audio_device()->Recording()); 666474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 667474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 668474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org void StopRecording() { 669474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->StopRecording()); 670474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_FALSE(audio_device()->Recording()); 671474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org } 672474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 6738324b525dce2c502bbd24b3946bbae207645cde9henrika int GetMaxSpeakerVolume() const { 6748324b525dce2c502bbd24b3946bbae207645cde9henrika uint32_t max_volume(0); 6758324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume)); 6768324b525dce2c502bbd24b3946bbae207645cde9henrika return max_volume; 6778324b525dce2c502bbd24b3946bbae207645cde9henrika } 6788324b525dce2c502bbd24b3946bbae207645cde9henrika 6798324b525dce2c502bbd24b3946bbae207645cde9henrika int GetMinSpeakerVolume() const { 6808324b525dce2c502bbd24b3946bbae207645cde9henrika uint32_t min_volume(0); 6818324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(0, audio_device()->MinSpeakerVolume(&min_volume)); 6828324b525dce2c502bbd24b3946bbae207645cde9henrika return min_volume; 6838324b525dce2c502bbd24b3946bbae207645cde9henrika } 6848324b525dce2c502bbd24b3946bbae207645cde9henrika 6858324b525dce2c502bbd24b3946bbae207645cde9henrika int GetSpeakerVolume() const { 6868324b525dce2c502bbd24b3946bbae207645cde9henrika uint32_t volume(0); 6878324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(0, audio_device()->SpeakerVolume(&volume)); 6888324b525dce2c502bbd24b3946bbae207645cde9henrika return volume; 6898324b525dce2c502bbd24b3946bbae207645cde9henrika } 6908324b525dce2c502bbd24b3946bbae207645cde9henrika 691474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org rtc::scoped_ptr<EventWrapper> test_is_done_; 69226b08605e2b99136fcc1cab0800234f469d6e236Peter Boström rtc::scoped_refptr<AudioDeviceModule> audio_device_; 693b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioParameters playout_parameters_; 694b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioParameters record_parameters_; 695523183b4aa2118b483967fccfdbe5b848c3eb18dhenrika rtc::scoped_ptr<BuildInfo> build_info_; 696474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org}; 697474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 698b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, ConstructDestruct) { 699474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org // Using the test fixture to create and destruct the audio device module. 700474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 701474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 702b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// We always ask for a default audio layer when the ADM is constructed. But the 703b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// ADM will then internally set the best suitable combination of audio layers, 704b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// for input and output based on if low-latency output audio in combination 705b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// with OpenSL ES is supported or not. This test ensures that the correct 706b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// selection is done. 707b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, VerifyDefaultAudioLayer) { 708b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika const AudioDeviceModule::AudioLayer audio_layer = GetActiveAudioLayer(); 709b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika bool low_latency_output = audio_manager()->IsLowLatencyPlayoutSupported(); 710b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer expected_audio_layer = low_latency_output ? 711b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio : 712b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::kAndroidJavaAudio; 713b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(expected_audio_layer, audio_layer); 714474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 715474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 716b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// Verify that it is possible to explicitly create the two types of supported 717b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// ADMs. These two tests overrides the default selection of native audio layer 718b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// by ignoring if the device supports low-latency output or not. 719b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo) { 720b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer expected_layer = 721b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio; 722b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer( 723b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika expected_layer); 724b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(expected_layer, active_layer); 725b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika} 726b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 727b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForJavaInBothDirections) { 728b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer expected_layer = 729b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::kAndroidJavaAudio; 730b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer( 731b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika expected_layer); 732b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(expected_layer, active_layer); 733b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika} 734b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 735b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// The Android ADM supports two different delay reporting modes. One for the 736b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// low-latency output path (in combination with OpenSL ES), and one for the 737b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// high-latency output path (Java backends in both directions). These two tests 738b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// verifies that the audio manager reports correct delay estimate given the 739b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// selected audio layer. Note that, this delay estimate will only be utilized 740b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// if the HW AEC is disabled. 741b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForHighLatencyOutputPath) { 742b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(kHighLatencyModeDelayEstimateInMilliseconds, 743b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika TestDelayOnAudioLayer(AudioDeviceModule::kAndroidJavaAudio)); 744b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika} 745b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 746b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForLowLatencyOutputPath) { 747b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(kLowLatencyModeDelayEstimateInMilliseconds, 748b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika TestDelayOnAudioLayer( 749b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio)); 750b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika} 751b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 752b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// Ensure that the ADM internal audio device buffer is configured to use the 753b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// correct set of parameters. 754b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, VerifyAudioDeviceBufferParameters) { 755b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(playout_parameters_.sample_rate(), 756b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika audio_device_buffer()->PlayoutSampleRate()); 757b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(record_parameters_.sample_rate(), 758b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika audio_device_buffer()->RecordingSampleRate()); 759b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(playout_parameters_.channels(), 760b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika audio_device_buffer()->PlayoutChannels()); 761b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(record_parameters_.channels(), 762b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika audio_device_buffer()->RecordingChannels()); 763b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika} 764b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 765b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 766b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, InitTerminate) { 767474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org // Initialization is part of the test fixture. 768474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_TRUE(audio_device()->Initialized()); 769474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->Terminate()); 770474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_FALSE(audio_device()->Initialized()); 771474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 772474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 773b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, Devices) { 774474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org // Device enumeration is not supported. Verify fixed values only. 775474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(1, audio_device()->PlayoutDevices()); 776474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(1, audio_device()->RecordingDevices()); 777474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 778474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 779b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, SpeakerVolumeShouldBeAvailable) { 780b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // The OpenSL ES output audio path does not support volume control. 781b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika if (!AudioLayerSupportsVolumeControl()) 782b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return; 7838324b525dce2c502bbd24b3946bbae207645cde9henrika bool available; 7848324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(0, audio_device()->SpeakerVolumeIsAvailable(&available)); 7858324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_TRUE(available); 7868324b525dce2c502bbd24b3946bbae207645cde9henrika} 7878324b525dce2c502bbd24b3946bbae207645cde9henrika 788b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, MaxSpeakerVolumeIsPositive) { 789b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // The OpenSL ES output audio path does not support volume control. 790b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika if (!AudioLayerSupportsVolumeControl()) 791b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return; 792b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika StartPlayout(); 7938324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_GT(GetMaxSpeakerVolume(), 0); 794b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika StopPlayout(); 7958324b525dce2c502bbd24b3946bbae207645cde9henrika} 7968324b525dce2c502bbd24b3946bbae207645cde9henrika 797b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, MinSpeakerVolumeIsZero) { 798b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // The OpenSL ES output audio path does not support volume control. 799b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika if (!AudioLayerSupportsVolumeControl()) 800b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return; 8018324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(GetMinSpeakerVolume(), 0); 8028324b525dce2c502bbd24b3946bbae207645cde9henrika} 8038324b525dce2c502bbd24b3946bbae207645cde9henrika 804b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, DefaultSpeakerVolumeIsWithinMinMax) { 805b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // The OpenSL ES output audio path does not support volume control. 806b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika if (!AudioLayerSupportsVolumeControl()) 807b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return; 8088324b525dce2c502bbd24b3946bbae207645cde9henrika const int default_volume = GetSpeakerVolume(); 8098324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_GE(default_volume, GetMinSpeakerVolume()); 8108324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_LE(default_volume, GetMaxSpeakerVolume()); 8118324b525dce2c502bbd24b3946bbae207645cde9henrika} 8128324b525dce2c502bbd24b3946bbae207645cde9henrika 813b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, SetSpeakerVolumeActuallySetsVolume) { 814b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // The OpenSL ES output audio path does not support volume control. 815b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika if (!AudioLayerSupportsVolumeControl()) 816b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika return; 8178324b525dce2c502bbd24b3946bbae207645cde9henrika const int default_volume = GetSpeakerVolume(); 8188324b525dce2c502bbd24b3946bbae207645cde9henrika const int max_volume = GetMaxSpeakerVolume(); 8198324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume)); 8208324b525dce2c502bbd24b3946bbae207645cde9henrika int new_volume = GetSpeakerVolume(); 8218324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(new_volume, max_volume); 8228324b525dce2c502bbd24b3946bbae207645cde9henrika EXPECT_EQ(0, audio_device()->SetSpeakerVolume(default_volume)); 8238324b525dce2c502bbd24b3946bbae207645cde9henrika} 8248324b525dce2c502bbd24b3946bbae207645cde9henrika 825b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// Tests that playout can be initiated, started and stopped. No audio callback 826b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// is registered in this test. 8279359b5b97810238e506350fdd0cb3d60001525f3Henrik Kjellander// Flaky on our trybots makes this test unusable. 8289359b5b97810238e506350fdd0cb3d60001525f3Henrik Kjellander// https://code.google.com/p/webrtc/issues/detail?id=5046 8299359b5b97810238e506350fdd0cb3d60001525f3Henrik KjellanderTEST_F(AudioDeviceTest, DISABLED_StartStopPlayout) { 830474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StartPlayout(); 831474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StopPlayout(); 832b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika StartPlayout(); 833b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika StopPlayout(); 834b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika} 835b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika 83682e20554cbf8152d67915e3ef764bad8064b6541henrika// Tests that recording can be initiated, started and stopped. No audio callback 83782e20554cbf8152d67915e3ef764bad8064b6541henrika// is registered in this test. 83882e20554cbf8152d67915e3ef764bad8064b6541henrikaTEST_F(AudioDeviceTest, StartStopRecording) { 83982e20554cbf8152d67915e3ef764bad8064b6541henrika StartRecording(); 84082e20554cbf8152d67915e3ef764bad8064b6541henrika StopRecording(); 84182e20554cbf8152d67915e3ef764bad8064b6541henrika StartRecording(); 84282e20554cbf8152d67915e3ef764bad8064b6541henrika StopRecording(); 84382e20554cbf8152d67915e3ef764bad8064b6541henrika} 84482e20554cbf8152d67915e3ef764bad8064b6541henrika 845b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// Verify that calling StopPlayout() will leave us in an uninitialized state 846b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika// which will require a new call to InitPlayout(). This test does not call 84791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg// StartPlayout() while being uninitialized since doing so will hit a 84891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg// RTC_DCHECK. 849b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, StopPlayoutRequiresInitToRestart) { 850b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(0, audio_device()->InitPlayout()); 851b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(0, audio_device()->StartPlayout()); 852b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(0, audio_device()->StopPlayout()); 853b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 854474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 855474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 856474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// Start playout and verify that the native audio layer starts asking for real 857474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// audio samples to play out using the NeedMorePlayData callback. 858b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, StartPlayoutVerifyCallbacks) { 859474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org MockAudioTransport mock(kPlayout); 86080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 861b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(), 862474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org kBytesPerSample, 863474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org playout_channels(), 864474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org playout_sample_rate(), 865474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org NotNull(), 866474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org _, _, _)) 867474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org .Times(AtLeast(kNumCallbacks)); 868474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 869474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StartPlayout(); 870474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org test_is_done_->Wait(kTestTimeOutInMilliseconds); 871474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StopPlayout(); 872474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 873474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 874474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// Start recording and verify that the native audio layer starts feeding real 875474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// audio samples via the RecordedDataIsAvailable callback. 876b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, StartRecordingVerifyCallbacks) { 877474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org MockAudioTransport mock(kRecording); 87880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 879474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), 880b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika record_frames_per_10ms_buffer(), 881474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org kBytesPerSample, 882b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika record_channels(), 883b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika record_sample_rate(), 884b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika total_delay_ms(), 885474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 0, 886474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 0, 887474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org false, 888474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org _)) 889474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org .Times(AtLeast(kNumCallbacks)); 890474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 891474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 892474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StartRecording(); 893474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org test_is_done_->Wait(kTestTimeOutInMilliseconds); 894474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StopRecording(); 895474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 896474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 897474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 898474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// Start playout and recording (full-duplex audio) and verify that audio is 899474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// active in both directions. 900b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, StartPlayoutAndRecordingVerifyCallbacks) { 901474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org MockAudioTransport mock(kPlayout | kRecording); 90280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 903b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(), 904474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org kBytesPerSample, 905474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org playout_channels(), 906474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org playout_sample_rate(), 907474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org NotNull(), 908474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org _, _, _)) 909474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org .Times(AtLeast(kNumCallbacks)); 910474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), 911b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika record_frames_per_10ms_buffer(), 912474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org kBytesPerSample, 913b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika record_channels(), 914b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika record_sample_rate(), 915b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika total_delay_ms(), 916474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 0, 917474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 0, 918474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org false, 919474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org _)) 920474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org .Times(AtLeast(kNumCallbacks)); 921474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 922474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StartPlayout(); 923474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StartRecording(); 924474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org test_is_done_->Wait(kTestTimeOutInMilliseconds); 925474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StopRecording(); 926474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StopPlayout(); 927474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 928474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 929474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// Start playout and read audio from an external PCM file when the audio layer 930474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// asks for data to play out. Real audio is played out in this test but it does 931474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org// not contain any explicit verification that the audio quality is perfect. 932b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) { 933474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org // TODO(henrika): extend test when mono output is supported. 9346955870806624479723addfae6dcf5d13968796cPeter Kasting EXPECT_EQ(1u, playout_channels()); 935474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org NiceMock<MockAudioTransport> mock(kPlayout); 93680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond; 93774d4792af574a90c4a13b3e57195883e2a546cbehenrika@webrtc.org std::string file_name = GetFileName(playout_sample_rate()); 93880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::scoped_ptr<FileAudioStream> file_audio_stream( 93980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org new FileAudioStream(num_callbacks, file_name, playout_sample_rate())); 94080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org mock.HandleCallbacks(test_is_done_.get(), 94180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org file_audio_stream.get(), 94280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org num_callbacks); 943b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika // SetMaxPlayoutVolume(); 944474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 945474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StartPlayout(); 946474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org test_is_done_->Wait(kTestTimeOutInMilliseconds); 947474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org StopPlayout(); 948474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} 949474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org 95080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Start playout and recording and store recorded data in an intermediate FIFO 95180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// buffer from which the playout side then reads its samples in the same order 95280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// as they were stored. Under ideal circumstances, a callback sequence would 95380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-' 95480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// means 'packet played'. Under such conditions, the FIFO would only contain 95580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// one packet on average. However, under more realistic conditions, the size 95680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// of the FIFO will vary more due to an unbalance between the two sides. 95780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// This test tries to verify that the device maintains a balanced callback- 95880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// sequence by running in loopback for ten seconds while measuring the size 95980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// (max and average) of the FIFO. The size of the FIFO is increased by the 96080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// recording side and decreased by the playout side. 96180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// TODO(henrika): tune the final test parameters after running tests on several 96280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// different devices. 963b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) { 964b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(record_channels(), playout_channels()); 965b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(record_sample_rate(), playout_sample_rate()); 96680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org NiceMock<MockAudioTransport> mock(kPlayout | kRecording); 96780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::scoped_ptr<FifoAudioStream> fifo_audio_stream( 968b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika new FifoAudioStream(playout_frames_per_10ms_buffer())); 96980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org mock.HandleCallbacks(test_is_done_.get(), 97080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org fifo_audio_stream.get(), 97180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org kFullDuplexTimeInSec * kNumCallbacksPerSecond); 9728324b525dce2c502bbd24b3946bbae207645cde9henrika SetMaxPlayoutVolume(); 97380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 97480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org StartRecording(); 97580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org StartPlayout(); 97680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, 97780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 1000 * kFullDuplexTimeInSec)); 97880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org StopPlayout(); 97980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org StopRecording(); 980dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting EXPECT_LE(fifo_audio_stream->average_size(), 10u); 981dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting EXPECT_LE(fifo_audio_stream->largest_size(), 20u); 98280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org} 98380d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 98480d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// Measures loopback latency and reports the min, max and average values for 98580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// a full duplex audio session. 98680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// The latency is measured like so: 98780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// - Insert impulses periodically on the output side. 98880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// - Detect the impulses on the input side. 98980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// - Measure the time difference between the transmit time and receive time. 99080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// - Store time differences in a vector and calculate min, max and average. 99180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// This test requires a special hardware called Audio Loopback Dongle. 99280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org// See http://source.android.com/devices/audio/loopback.html for details. 993b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrikaTEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) { 994b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(record_channels(), playout_channels()); 995b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika EXPECT_EQ(record_sample_rate(), playout_sample_rate()); 99680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org NiceMock<MockAudioTransport> mock(kPlayout | kRecording); 99780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream( 998b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer())); 99980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org mock.HandleCallbacks(test_is_done_.get(), 100080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org latency_audio_stream.get(), 100180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org kMeasureLatencyTimeInSec * kNumCallbacksPerSecond); 100280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 10038324b525dce2c502bbd24b3946bbae207645cde9henrika SetMaxPlayoutVolume(); 1004b26198972c1fcb4aa7abaf3895b007e301e7d5dchenrika DisableBuiltInAECIfAvailable(); 100580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org StartRecording(); 100680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org StartPlayout(); 100780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, 100880d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 1000 * kMeasureLatencyTimeInSec)); 100980d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org StopPlayout(); 101080d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org StopRecording(); 101180d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org // Verify that the correct number of transmitted impulses are detected. 101280d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org EXPECT_EQ(latency_audio_stream->num_latency_values(), 1013dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting static_cast<size_t>( 1014dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1)); 101580d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org latency_audio_stream->PrintResults(); 101680d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org} 101780d9aeeda530aaf7e1851b381f1f7545a876d75ehenrika@webrtc.org 1018474d1eb22376898b36bcd04b0ce3860fa12fd984henrika@webrtc.org} // namespace webrtc 1019