15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include <vector> 6bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/file_util.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/files/file_path.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/path_service.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/media/webrtc_audio_capturer.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/webrtc_audio_device_impl.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/webrtc_audio_renderer.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/renderer/media/webrtc_local_audio_track.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/render_thread_impl.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/test/webrtc_audio_device_test.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_manager_base.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_hardware_config.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/webrtc/voice_engine/include/voe_audio_processing.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/webrtc/voice_engine/include/voe_base.h" 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/webrtc/voice_engine/include/voe_codec.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/webrtc/voice_engine/include/voe_external_media.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/webrtc/voice_engine/include/voe_file.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/webrtc/voice_engine/include/voe_network.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/win/windows_version.h" 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using media::AudioParameters; 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using media::CHANNEL_LAYOUT_STEREO; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AnyNumber; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::InvokeWithoutArgs; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::StrEq; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kRenderViewId = 1; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The number of packers that RunWebRtcLoopbackTimeTest() uses for measurement. 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kNumberOfPacketsForLoopbackTest = 100; 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The hardware latency we feed to WebRtc. 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kHardwareLatencyInMs = 50; 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<media::AudioHardwareConfig> CreateRealHardwareConfig( 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::AudioManager* manager) { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AudioParameters output_parameters = 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager->GetDefaultOutputStreamParameters(); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AudioParameters input_parameters = 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager->GetInputStreamParameters( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::AudioManagerBase::kDefaultDeviceId); 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr(new media::AudioHardwareConfig( 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input_parameters, output_parameters)); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return true if at least one element in the array matches |value|. 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FindElementInArray(const int* array, int size, int value) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (std::find(&array[0], &array[0] + size, value) != &array[size]); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This method returns false if a non-supported rate is detected on the 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// input or output side. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(henrika): add support for automatic fallback to Windows Wave audio 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if a non-supported rate is detected. It is probably better to detect 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// invalid audio settings by actually trying to open the audio streams instead 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of relying on hard coded conditions. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HardwareSampleRatesAreValid() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These are the currently supported hardware sample rates in both directions. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual WebRTC client can limit these ranges further depending on 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // platform but this is the maximum range we support today. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int valid_input_rates[] = {16000, 32000, 44100, 48000, 96000}; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int valid_output_rates[] = {16000, 32000, 44100, 48000, 96000}; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::AudioHardwareConfig* hardware_config = 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderThreadImpl::current()->GetAudioHardwareConfig(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the input sample rate. 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int input_sample_rate = hardware_config->GetInputSampleRate(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FindElementInArray(valid_input_rates, arraysize(valid_input_rates), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_sample_rate)) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Non-supported input sample rate detected."; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Given that the input rate was OK, verify the output rate as well. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int output_sample_rate = hardware_config->GetOutputSampleRate(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FindElementInArray(valid_output_rates, arraysize(valid_output_rates), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_sample_rate)) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Non-supported output sample rate detected."; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Utility method which creates and initializes the audio capturer and adds it 107bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// to WebRTC audio device. This method should be used in tests where 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HardwareSampleRatesAreValid() has been called and returned true. 109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochbool CreateAndInitializeCapturer(WebRtcAudioDeviceImpl* webrtc_audio_device) { 110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch DCHECK(webrtc_audio_device); 111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcAudioCapturer> capturer( 112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch WebRtcAudioCapturer::CreateCapturer()); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::AudioHardwareConfig* hardware_config = 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderThreadImpl::current()->GetAudioHardwareConfig(); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use native capture sample rate and channel configuration to get some 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // action in this test. 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int sample_rate = hardware_config->GetInputSampleRate(); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::ChannelLayout channel_layout = 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hardware_config->GetInputChannelLayout(); 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!capturer->Initialize(kRenderViewId, channel_layout, sample_rate, 0, 1, 123d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) media::AudioManagerBase::kDefaultDeviceId, 0, 0, 124d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) media::AudioParameters::NO_EFFECTS)) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 126bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 127bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 128bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Add the capturer to the WebRtcAudioDeviceImpl. 129bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch webrtc_audio_device->AddAudioCapturer(capturer); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 134bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Create and start a local audio track. Starting the audio track will connect 135bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// the audio track to the capturer and also start the source of the capturer. 136bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Also, connect the sink to the audio track. 137bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochscoped_refptr<WebRtcLocalAudioTrack> 138bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochCreateAndStartLocalAudioTrack(WebRtcAudioCapturer* capturer, 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PeerConnectionAudioSink* sink) { 140bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcLocalAudioTrack> local_audio_track( 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(std::string(), capturer, NULL, NULL, NULL)); 142bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch local_audio_track->AddSink(sink); 143bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch local_audio_track->Start(); 144bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return local_audio_track; 145bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 146bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit WebRTCMediaProcessImpl(base::WaitableEvent* event) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : event_(event), 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_id_(-1), 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(webrtc::kPlaybackPerChannel), 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_size_(0), 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_rate_(0), 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels_(0) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~WebRTCMediaProcessImpl() {} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(henrika): Refactor in WebRTC and convert to Chrome coding style. 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void Process(int channel, 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::ProcessingTypes type, 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int16_t audio_10ms[], 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int length, 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int sampling_freq, 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_stereo) OVERRIDE { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_id_ = channel; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_ = type; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_size_ = length; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_rate_ = sampling_freq; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels_ = (is_stereo ? 2 : 1); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Signal that a new callback has been received. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_->Signal(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int channel_id() const { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_id_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type() const { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type_; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int packet_size() const { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return packet_size_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sample_rate() const { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sample_rate_; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent* event_; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int channel_id_; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webrtc::ProcessingTypes type_; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int packet_size_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sample_rate_; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int channels_; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable base::Lock lock_; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WebRTCMediaProcessImpl); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TODO(xians): Use MediaStreamAudioSink. 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MockMediaStreamAudioSink : public PeerConnectionAudioSink { 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit MockMediaStreamAudioSink(base::WaitableEvent* event) 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : event_(event) { 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(event_); 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~MockMediaStreamAudioSink() {} 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // PeerConnectionAudioSink implementation. 219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual int OnData(const int16* audio_data, 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int sample_rate, 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int number_of_channels, 222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int number_of_frames, 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::vector<int>& channels, 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int audio_delay_milliseconds, 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int current_volume, 226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool need_audio_processing, 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool key_pressed) OVERRIDE { 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Signal that a callback has been received. 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_->Signal(); 230bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set the format for the capture audio parameters. 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnSetFormat( 23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const media::AudioParameters& params) OVERRIDE {} 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WaitableEvent* event_; 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MockMediaStreamAudioSink); 24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class MockWebRtcAudioRendererSource : public WebRtcAudioRendererSource { 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) explicit MockWebRtcAudioRendererSource(base::WaitableEvent* event) 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : event_(event) { 24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(event_); 24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~MockWebRtcAudioRendererSource() {} 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // WebRtcAudioRendererSource implementation. 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void RenderData(uint8* audio_data, 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int number_of_channels, 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int number_of_frames, 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int audio_delay_milliseconds) OVERRIDE { 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Signal that a callback has been received. 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Initialize the memory to zero to avoid uninitialized warning from 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Valgrind. 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) memset(audio_data, 0, 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sizeof(int16) * number_of_channels * number_of_frames); 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_->Signal(); 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void SetRenderFormat(const media::AudioParameters& params) OVERRIDE { 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void RemoveAudioRenderer(WebRtcAudioRenderer* renderer) OVERRIDE {}; 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WaitableEvent* event_; 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MockWebRtcAudioRendererSource); 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Prints numerical information to stdout in a controlled format so we can plot 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// the result. 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PrintPerfResultMs(const char* graph, const char* trace, float time_ms) { 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string times; 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::StringAppendF(×, "%.2f,", time_ms); 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string result = base::StringPrintf( 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "%sRESULT %s%s: %s= %s%s%s %s\n", "*", graph, "", 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) trace, "[", times.c_str(), "]", "ms"); 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fflush(stdout); 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) printf("%s", result.c_str()); 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fflush(stdout); 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ReadDataFromSpeechFile(char* data, int length) { 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath data_file; 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &data_file)); 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_file = 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_file.Append(FILE_PATH_LITERAL("media")) 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) .Append(FILE_PATH_LITERAL("test")) 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) .Append(FILE_PATH_LITERAL("data")) 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) .Append(FILE_PATH_LITERAL("speech_16b_stereo_48kHz.raw")); 2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(base::PathExists(data_file)); 29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 data_file_size64 = 0; 299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(base::GetFileSize(data_file, &data_file_size64)); 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_EQ(length, base::ReadFile(data_file, data, length)); 30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(data_file_size64 > length); 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void SetChannelCodec(webrtc::VoiceEngine* engine, int channel) { 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(xians): move the codec as an input param to this function, and add 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tests for different codecs, also add support to Android and IOS. 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if !defined(OS_ANDROID) && !defined(OS_IOS) 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::CodecInst isac; 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) strcpy(isac.plname, "ISAC"); 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) isac.pltype = 104; 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) isac.pacsize = 960; 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) isac.plfreq = 32000; 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) isac.channels = 1; 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) isac.rate = -1; 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScopedWebRTCPtr<webrtc::VoECodec> codec(engine); 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, codec->SetRecPayloadType(channel, isac)); 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, codec->SetSendCodec(channel, isac)); 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Returns the time in millisecond for sending packets to WebRtc for encoding, 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// signal processing, decoding and receiving them back. 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int RunWebRtcLoopbackTimeTest(media::AudioManager* manager, 32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool enable_apm) { 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new WebRtcAudioDeviceImpl()); 32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(engine.valid()); 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(base.valid()); 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int err = base->Init(webrtc_audio_device.get()); 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, err); 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // We use OnSetFormat() and SetRenderFormat() to configure the audio 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // parameters so that this test can run on machine without hardware device. 33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const media::AudioParameters params = media::AudioParameters( 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) media::AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 48000, 2, 480); 339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PeerConnectionAudioSink* capturer_sink = 340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<PeerConnectionAudioSink*>(webrtc_audio_device.get()); 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WebRtcAudioRendererSource* renderer_source = 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<WebRtcAudioRendererSource*>(webrtc_audio_device.get()); 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) renderer_source->SetRenderFormat(params); 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Turn on/off all the signal processing components like AGC, AEC and NS. 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEAudioProcessing> audio_processing(engine.get()); 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(audio_processing.valid()); 34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) audio_processing->SetAgcStatus(enable_apm); 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) audio_processing->SetNsStatus(enable_apm); 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) audio_processing->SetEcStatus(enable_apm); 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Create a voice channel for the WebRtc. 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int channel = base->CreateChannel(); 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_NE(-1, channel); 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetChannelCodec(engine.get(), channel); 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Use our fake network transmission and start playout and recording. 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScopedWebRTCPtr<webrtc::VoENetwork> network(engine.get()); 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(network.valid()); 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<WebRTCTransportImpl> transport( 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new WebRTCTransportImpl(network.get())); 36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, network->RegisterExternalTransport(channel, *transport.get())); 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->StartPlayout(channel)); 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->StartSend(channel)); 36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Read speech data from a speech test file. 367bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch const int input_packet_size = 368bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch params.frames_per_buffer() * 2 * params.channels(); 36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int num_output_channels = webrtc_audio_device->output_channels(); 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int output_packet_size = webrtc_audio_device->output_buffer_size() * 2 * 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) num_output_channels; 37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t length = input_packet_size * kNumberOfPacketsForLoopbackTest; 37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<char[]> capture_data(new char[length]); 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReadDataFromSpeechFile(capture_data.get(), length); 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Start the timer. 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<uint8[]> buffer(new uint8[output_packet_size]); 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Time start_time = base::Time::Now(); 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int delay = 0; 380bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch std::vector<int> voe_channels; 381bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch voe_channels.push_back(channel); 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int j = 0; j < kNumberOfPacketsForLoopbackTest; ++j) { 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Sending fake capture data to WebRtc. 384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) capturer_sink->OnData( 38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) reinterpret_cast<int16*>(capture_data.get() + input_packet_size * j), 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.sample_rate(), 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.channels(), 3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.frames_per_buffer(), 389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) voe_channels, 3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kHardwareLatencyInMs, 3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1.0, 3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) enable_apm, 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) false); 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Receiving data from WebRtc. 39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) renderer_source->RenderData( 39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) reinterpret_cast<uint8*>(buffer.get()), 39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) num_output_channels, webrtc_audio_device->output_buffer_size(), 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kHardwareLatencyInMs + delay); 40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delay = (base::Time::Now() - start_time).InMilliseconds(); 40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int latency = (base::Time::Now() - start_time).InMilliseconds(); 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->StopSend(channel)); 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->StopPlayout(channel)); 40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->DeleteChannel(channel)); 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->Terminate()); 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return latency; 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Trivial test which verifies that one part of the test harness 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (HardwareSampleRatesAreValid()) works as intended for all supported 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hardware input sample rates. 418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, TestValidInputRates) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int valid_rates[] = {16000, 32000, 44100, 48000, 96000}; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we will approve all rates listed in |valid_rates|. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(valid_rates); ++i) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FindElementInArray(valid_rates, arraysize(valid_rates), 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valid_rates[i])); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that any value outside the valid range results in negative 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // find results. 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int invalid_rates[] = {-1, 0, 8000, 11025, 22050, 192000}; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(invalid_rates); ++i) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FindElementInArray(valid_rates, arraysize(valid_rates), 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid_rates[i])); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Trivial test which verifies that one part of the test harness 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (HardwareSampleRatesAreValid()) works as intended for all supported 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hardware output sample rates. 439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, TestValidOutputRates) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int valid_rates[] = {44100, 48000, 96000}; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we will approve all rates listed in |valid_rates|. 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(valid_rates); ++i) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(FindElementInArray(valid_rates, arraysize(valid_rates), 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valid_rates[i])); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that any value outside the valid range results in negative 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // find results. 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int invalid_rates[] = {-1, 0, 8000, 11025, 22050, 32000, 192000}; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(invalid_rates); ++i) { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(FindElementInArray(valid_rates, arraysize(valid_rates), 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid_rates[i])); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Basic test that instantiates and initializes an instance of 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebRtcAudioDeviceImpl. 459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, Construct) { 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN) 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test crashes on Win XP bots. 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (base::win::GetVersion() <= base::win::VERSION_XP) 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioParameters input_params( 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioParameters::AUDIO_PCM_LOW_LATENCY, 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::CHANNEL_LAYOUT_MONO, 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48000, 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16, 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 480); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioParameters output_params( 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioParameters::AUDIO_PCM_LOW_LATENCY, 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::CHANNEL_LAYOUT_STEREO, 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48000, 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16, 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 480); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media::AudioHardwareConfig audio_config(input_params, output_params); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetAudioHardwareConfig(&audio_config); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new WebRtcAudioDeviceImpl()); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(engine.valid()); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int err = base->Init(webrtc_audio_device.get()); 491bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch EXPECT_TRUE(CreateAndInitializeCapturer(webrtc_audio_device.get())); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, err); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->Terminate()); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that a call to webrtc::VoEBase::StartPlayout() starts audio output 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with the correct set of parameters. A WebRtcAudioDeviceImpl instance will 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be utilized to implement the actual audio path. The test registers a 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// webrtc::VoEExternalMedia implementation to hijack the output audio and 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// verify that streaming starts correctly. 50158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// TODO(henrika): include on Android as well as soon as alla race conditions 50258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// in OpenSLES are resolved. 50358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_ANDROID) 50458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MAYBE_StartPlayout DISABLED_StartPlayout 50558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else 50658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MAYBE_StartPlayout StartPlayout 50758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 50858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, MAYBE_StartPlayout) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_output_devices_) { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "No output device detected."; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<media::AudioHardwareConfig> config = 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateRealHardwareConfig(audio_manager_.get()); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetAudioHardwareConfig(config.get()); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HardwareSampleRatesAreValid()) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(engine.valid()); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(base.valid()); 52558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 52758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new WebRtcAudioDeviceImpl()); 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int err = base->Init(webrtc_audio_device.get()); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, err); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEExternalMedia> external_media(engine.get()); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(external_media.valid()); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent event(false, false); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebRTCMediaProcessImpl> media_process( 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new WebRTCMediaProcessImpl(&event)); 53658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int ch = base->CreateChannel(); 53758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_NE(-1, ch); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, external_media->RegisterExternalMediaProcessing( 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ch, webrtc::kPlaybackPerChannel, *media_process.get())); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StartPlayout(ch)); 54258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<WebRtcAudioRenderer> renderer( 54358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CreateDefaultWebRtcAudioRenderer(kRenderViewId)); 54458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<MediaStreamAudioRenderer> proxy( 54558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) renderer->CreateSharedAudioRendererProxy()); 54658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_TRUE(webrtc_audio_device->SetAudioRenderer(renderer.get())); 54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Start(); 54858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Play(); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout())); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForIOThreadCompletion(); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(webrtc_audio_device->Playing()); 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(webrtc_audio_device->Recording()); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ch, media_process->channel_id()); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(webrtc::kPlaybackPerChannel, media_process->type()); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(80, media_process->packet_size()); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(8000, media_process->sample_rate()); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, external_media->DeRegisterExternalMediaProcessing( 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ch, webrtc::kPlaybackPerChannel)); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StopPlayout(ch)); 56358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Stop(); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->DeleteChannel(ch)); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->Terminate()); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that a call to webrtc::VoEBase::StartRecording() starts audio input 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with the correct set of parameters. A WebRtcAudioDeviceImpl instance will 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be utilized to implement the actual audio path. The test registers a 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// webrtc::VoEExternalMedia implementation to hijack the input audio and 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// verify that streaming starts correctly. An external transport implementation 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is also required to ensure that "sending" can start without actually trying 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to send encoded packets to the network. Our main interest here is to ensure 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the audio capturing starts as it should. 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Disabled when running headless since the bots don't have the required config. 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(leozwang): Because ExternalMediaProcessing is disabled in webrtc, 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// disable this unit test on Android for now. 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_StartRecording DISABLED_StartRecording 582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#elif defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This test is failing on ARM linux: http://crbug.com/238490 584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define MAYBE_StartRecording DISABLED_StartRecording 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 5862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Flakily hangs on all other platforms as well: crbug.com/268376. 5872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// When the flakiness has been fixed, you probably want to leave it disabled 5882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// on the above platforms. 5892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#define MAYBE_StartRecording DISABLED_StartRecording 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 5912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, MAYBE_StartRecording) { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_input_devices_ || !has_output_devices_) { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Missing audio devices."; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<media::AudioHardwareConfig> config = 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateRealHardwareConfig(audio_manager_.get()); 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetAudioHardwareConfig(config.get()); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HardwareSampleRatesAreValid()) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(tommi): extend MediaObserver and MockMediaObserver with support 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for new interfaces, like OnSetAudioStreamRecording(). When done, add 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EXPECT_CALL() macros here. 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new WebRtcAudioDeviceImpl()); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(engine.valid()); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(base.valid()); 616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int err = base->Init(webrtc_audio_device.get()); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, err); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ch = base->CreateChannel(); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(-1, ch); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEExternalMedia> external_media(engine.get()); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(external_media.valid()); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent event(false, false); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebRTCMediaProcessImpl> media_process( 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new WebRTCMediaProcessImpl(&event)); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, external_media->RegisterExternalMediaProcessing( 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ch, webrtc::kRecordingPerChannel, *media_process.get())); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We must add an external transport implementation to be able to start 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // recording without actually sending encoded packets to the network. All 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we want to do here is to verify that audio capturing starts as it should. 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoENetwork> network(engine.get()); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebRTCTransportImpl> transport( 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new WebRTCTransportImpl(network.get())); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, network->RegisterExternalTransport(ch, *transport.get())); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StartSend(ch)); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 640bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Create and initialize the capturer which starts the source of the data 641bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // flow. 642bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch EXPECT_TRUE(CreateAndInitializeCapturer(webrtc_audio_device.get())); 643bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 644bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Create and start a local audio track which is bridging the data flow 645bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // between the capturer and WebRtcAudioDeviceImpl. 646bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcLocalAudioTrack> local_audio_track( 647bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch CreateAndStartLocalAudioTrack(webrtc_audio_device->GetDefaultCapturer(), 648bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch webrtc_audio_device)); 649bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // connect the VoE voice channel to the audio track 650bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(local_audio_track.get())-> 651bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(ch); 652bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 653bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Verify we get the data flow. 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout())); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForIOThreadCompletion(); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(webrtc_audio_device->Playing()); 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(webrtc_audio_device->Recording()); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ch, media_process->channel_id()); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(webrtc::kRecordingPerChannel, media_process->type()); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(80, media_process->packet_size()); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(8000, media_process->sample_rate()); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, external_media->DeRegisterExternalMediaProcessing( 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ch, webrtc::kRecordingPerChannel)); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StopSend(ch)); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) webrtc_audio_device->GetDefaultCapturer()->Stop(); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->DeleteChannel(ch)); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->Terminate()); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Uses WebRtcAudioDeviceImpl to play a local wave file. 67458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// TODO(henrika): include on Android as well as soon as alla race conditions 67558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// in OpenSLES are resolved. 67658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_ANDROID) 67758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MAYBE_PlayLocalFile DISABLED_PlayLocalFile 67858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else 67958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MAYBE_PlayLocalFile PlayLocalFile 68058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 68158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, MAYBE_PlayLocalFile) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_output_devices_) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "No output device detected."; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string file_path( 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm"))); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<media::AudioHardwareConfig> config = 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateRealHardwareConfig(audio_manager_.get()); 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetAudioHardwareConfig(config.get()); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HardwareSampleRatesAreValid()) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(engine.valid()); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(base.valid()); 70158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 70258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 70358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new WebRtcAudioDeviceImpl()); 704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int err = base->Init(webrtc_audio_device.get()); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, err); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ch = base->CreateChannel(); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(-1, ch); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StartPlayout(ch)); 70958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<WebRtcAudioRenderer> renderer( 71058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CreateDefaultWebRtcAudioRenderer(kRenderViewId)); 71158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<MediaStreamAudioRenderer> proxy( 71258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) renderer->CreateSharedAudioRendererProxy()); 71358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_TRUE(webrtc_audio_device->SetAudioRenderer(renderer.get())); 71458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Start(); 71558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Play(); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEFile> file(engine.get()); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(file.valid()); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int duration = 0; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, file->GetFileDuration(file_path.c_str(), duration, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webrtc::kFileFormatPcm16kHzFile)); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(0, duration); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, file->StartPlayingFileLocally(ch, file_path.c_str(), false, 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webrtc::kFileFormatPcm16kHzFile)); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Play 2 seconds worth of audio and then quit. 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.PostDelayedTask(FROM_HERE, 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::QuitClosure(), 73058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeDelta::FromSeconds(2)); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Stop(); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StopSend(ch)); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StopPlayout(ch)); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->DeleteChannel(ch)); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->Terminate()); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Uses WebRtcAudioDeviceImpl to play out recorded audio in loopback. 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An external transport implementation is utilized to feed back RTP packets 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which are recorded, encoded, packetized into RTP packets and finally 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "transmitted". The RTP packets are then fed back into the VoiceEngine 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where they are decoded and played out on the default audio output device. 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Disabled when running headless since the bots don't have the required config. 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(henrika): improve quality by using a wideband codec, enabling noise- 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// suppressions etc. 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// FullDuplexAudioWithAGC is flaky on Android, disable it for now. 749bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Also flakily hangs on Windows: crbug.com/269348. 750bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#if defined(OS_ANDROID) || defined(OS_WIN) 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_FullDuplexAudioWithAGC DISABLED_FullDuplexAudioWithAGC 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_FullDuplexAudioWithAGC FullDuplexAudioWithAGC 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 755a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, MAYBE_FullDuplexAudioWithAGC) { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_output_devices_ || !has_input_devices_) { 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Missing audio devices."; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<media::AudioHardwareConfig> config = 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateRealHardwareConfig(audio_manager_.get()); 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetAudioHardwareConfig(config.get()); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HardwareSampleRatesAreValid()) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(engine.valid()); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(base.valid()); 77258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 77358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 77458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new WebRtcAudioDeviceImpl()); 775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int err = base->Init(webrtc_audio_device.get()); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, err); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEAudioProcessing> audio_processing(engine.get()); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(audio_processing.valid()); 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On Android, by default AGC is off. 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool enabled = true; 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webrtc::AgcModes agc_mode = webrtc::kAgcDefault; 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, audio_processing->GetAgcStatus(enabled, agc_mode)); 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(enabled); 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled = false; 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webrtc::AgcModes agc_mode = webrtc::kAgcDefault; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, audio_processing->GetAgcStatus(enabled, agc_mode)); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(enabled); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(agc_mode, webrtc::kAgcAdaptiveAnalog); 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ch = base->CreateChannel(); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(-1, ch); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 797bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch EXPECT_TRUE(CreateAndInitializeCapturer(webrtc_audio_device.get())); 798bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcLocalAudioTrack> local_audio_track( 799bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch CreateAndStartLocalAudioTrack(webrtc_audio_device->GetDefaultCapturer(), 800bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch webrtc_audio_device)); 801bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // connect the VoE voice channel to the audio track 802bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(local_audio_track.get())-> 803bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(ch); 804bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedWebRTCPtr<webrtc::VoENetwork> network(engine.get()); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(network.valid()); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebRTCTransportImpl> transport( 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new WebRTCTransportImpl(network.get())); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, network->RegisterExternalTransport(ch, *transport.get())); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StartPlayout(ch)); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StartSend(ch)); 81258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<WebRtcAudioRenderer> renderer( 81358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CreateDefaultWebRtcAudioRenderer(kRenderViewId)); 81458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<MediaStreamAudioRenderer> proxy( 81558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) renderer->CreateSharedAudioRendererProxy()); 81658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_TRUE(webrtc_audio_device->SetAudioRenderer(renderer.get())); 81758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Start(); 81858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Play(); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VLOG(0) << ">> You should now be able to hear yourself in loopback..."; 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.PostDelayedTask(FROM_HERE, 822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::QuitClosure(), 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(2)); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) webrtc_audio_device->GetDefaultCapturer()->Stop(); 82758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Stop(); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StopSend(ch)); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->StopPlayout(ch)); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->DeleteChannel(ch)); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, base->Terminate()); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Test times out on bots, see http://crbug.com/247447 836a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, DISABLED_WebRtcRecordingSetupTime) { 83790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!has_input_devices_) { 83890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(WARNING) << "Missing audio capture devices."; 83990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 84090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 84190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 84290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<media::AudioHardwareConfig> config = 84390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateRealHardwareConfig(audio_manager_.get()); 84490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetAudioHardwareConfig(config.get()); 84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 84690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!HardwareSampleRatesAreValid()) 84790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 84890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 84990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( 85090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new WebRtcAudioDeviceImpl()); 85190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 85290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); 85390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(engine.valid()); 85490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 85590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScopedWebRTCPtr<webrtc::VoEBase> base(engine.get()); 85690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(base.valid()); 857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int err = base->Init(webrtc_audio_device.get()); 85890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(0, err); 85990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 860bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch int ch = base->CreateChannel(); 861bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch EXPECT_NE(-1, ch); 86290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 863bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch EXPECT_TRUE(CreateAndInitializeCapturer(webrtc_audio_device.get())); 86490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WaitableEvent event(false, false); 865a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<MockMediaStreamAudioSink> sink( 866a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new MockMediaStreamAudioSink(&event)); 86790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 868bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Create and start a local audio track. Starting the audio track will connect 869bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // the audio track to the capturer and also start the source of the capturer. 870bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcLocalAudioTrack> local_audio_track( 871bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch CreateAndStartLocalAudioTrack( 872bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch webrtc_audio_device->GetDefaultCapturer().get(), sink.get())); 873bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 874bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // connect the VoE voice channel to the audio track. 875bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<webrtc::AudioTrackInterface*>(local_audio_track.get())-> 876bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetRenderer()->AddChannel(ch); 87790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 87890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Time start_time = base::Time::Now(); 87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->StartSend(ch)); 88090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 88190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout())); 88290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int delay = (base::Time::Now() - start_time).InMilliseconds(); 88390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PrintPerfResultMs("webrtc_recording_setup_c", "t", delay); 88490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 885f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) webrtc_audio_device->GetDefaultCapturer()->Stop(); 88690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->StopSend(ch)); 88790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->DeleteChannel(ch)); 88890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, base->Terminate()); 88990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 89090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 89158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 89258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// TODO(henrika): include on Android as well as soon as alla race conditions 89358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// in OpenSLES are resolved. 89458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_ANDROID) 89558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MAYBE_WebRtcPlayoutSetupTime DISABLED_WebRtcPlayoutSetupTime 89658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else 89758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MAYBE_WebRtcPlayoutSetupTime WebRtcPlayoutSetupTime 89858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 89958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, MAYBE_WebRtcPlayoutSetupTime) { 90090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!has_output_devices_) { 90190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(WARNING) << "No output device detected."; 90290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 90390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 90490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 90590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<media::AudioHardwareConfig> config = 90690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateRealHardwareConfig(audio_manager_.get()); 90790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetAudioHardwareConfig(config.get()); 90890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 90990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!HardwareSampleRatesAreValid()) 91090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 91190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 91290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WaitableEvent event(false, false); 91390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<MockWebRtcAudioRendererSource> renderer_source( 91490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new MockWebRtcAudioRendererSource(&event)); 91558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 91658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<WebRtcAudioRenderer> renderer( 91758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CreateDefaultWebRtcAudioRenderer(kRenderViewId)); 91890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) renderer->Initialize(renderer_source.get()); 91958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<MediaStreamAudioRenderer> proxy( 92058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) renderer->CreateSharedAudioRendererProxy()); 92158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Start(); 92290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 92390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Start the timer and playout. 92490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Time start_time = base::Time::Now(); 92558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Play(); 92690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout())); 92790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int delay = (base::Time::Now() - start_time).InMilliseconds(); 92890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PrintPerfResultMs("webrtc_playout_setup_c", "t", delay); 92990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 93058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) proxy->Stop(); 93190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 93290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Timing out on ARM linux bot: http://crbug.com/238490 935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MAYBE_WebRtcLoopbackTimeWithoutSignalProcessing \ 936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISABLED_WebRtcLoopbackTimeWithoutSignalProcessing 937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else 938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MAYBE_WebRtcLoopbackTimeWithoutSignalProcessing \ 939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebRtcLoopbackTimeWithoutSignalProcessing 940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 942a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, 943a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MAYBE_WebRtcLoopbackTimeWithoutSignalProcessing) { 944f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN) 945f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This test hangs on WinXP: see http://crbug.com/318189. 946f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (base::win::GetVersion() <= base::win::VERSION_XP) { 947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(WARNING) << "Test disabled due to the test hangs on WinXP."; 948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 949f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 95190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int latency = RunWebRtcLoopbackTimeTest(audio_manager_.get(), false); 95290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PrintPerfResultMs("webrtc_loopback_without_sigal_processing (100 packets)", 95390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "t", latency); 95490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 95590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Timing out on ARM linux bot: http://crbug.com/238490 958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MAYBE_WebRtcLoopbackTimeWithSignalProcessing \ 959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISABLED_WebRtcLoopbackTimeWithSignalProcessing 960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else 961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MAYBE_WebRtcLoopbackTimeWithSignalProcessing \ 962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebRtcLoopbackTimeWithSignalProcessing 963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 965a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(MAYBE_WebRTCAudioDeviceTest, 966a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MAYBE_WebRtcLoopbackTimeWithSignalProcessing) { 967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN) 968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This test hangs on WinXP: see http://crbug.com/318189. 969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (base::win::GetVersion() <= base::win::VERSION_XP) { 970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(WARNING) << "Test disabled due to the test hangs on WinXP."; 971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 97490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int latency = RunWebRtcLoopbackTimeTest(audio_manager_.get(), true); 97590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PrintPerfResultMs("webrtc_loopback_with_signal_processing (100 packets)", 97690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "t", latency); 97790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 97890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 980